insert语句删除无用字段-正则表达式

package com.example.unittesting;

import java.util.*;
import java.util.regex.*;

public class SqlUtils {

    /**
     * 改写 INSERT SQL,移除指定字段及其对应的值
     *
     * @param sql               原始 INSERT SQL
     * @param columnsToRemove   要移除的字段名列表
     * @return                  改写后的 SQL
     */
    public static String insertSqlUpdate(String sql, List<String> columnsToRemove) {
        if (sql == null || sql.trim().isEmpty() || columnsToRemove == null || columnsToRemove.isEmpty()) {
            return sql;
        }

        // 去除 SQL 两边的空白
        sql = sql.trim();

        // 改进的正则表达式,处理括号嵌套和特殊字符
        Pattern pattern = Pattern.compile(
                "(?i)(INSERT\\s+INTO\\s+[\\w\\.]+)\\s*\\((.*?)\\)\\s*VALUES\\s*\\((.*?)\\)(;?)$",
                Pattern.CASE_INSENSITIVE | Pattern.DOTALL
        );

        Matcher matcher = pattern.matcher(sql);

        if (!matcher.find()) {
            throw new IllegalArgumentException("SQL format not supported or invalid: " + sql);
        }

        // 提取字段和值部分
        String columnsStr = matcher.group(2).trim();
        String valuesStr = matcher.group(3).trim();
        String trailingSemicolon = matcher.group(4);

        List<String> columns = splitSqlList(columnsStr);
        List<String> values = splitSqlList(valuesStr);

        if (columns.size() != values.size()) {
            throw new IllegalArgumentException("Columns count and values count mismatch in SQL: " + sql);
        }

        Set<String> removeSet = new HashSet<>();
        for (String col : columnsToRemove) {
            removeSet.add(col.trim().toLowerCase());
        }

        List<String> newColumns = new ArrayList<>();
        List<String> newValues = new ArrayList<>();

        for (int i = 0; i < columns.size(); i++) {
            String col = columns.get(i).trim();
            if (!removeSet.contains(col.toLowerCase())) {
                newColumns.add(columns.get(i));
                newValues.add(values.get(i));
            }
        }

        // 拼接新 SQL,保留原SQL的分号
        return String.format("%s (%s) VALUES (%s)%s",
                matcher.group(1), // INSERT INTO ...
                String.join(", ", newColumns),
                String.join(", ", newValues),
                trailingSemicolon);
    }

    /**
     * 拆分 SQL 列表,如 "c1, c2, c3" => ["c1", "c2", "c3"]
     * 增强了对引号和括号的处理
     */
    private static List<String> splitSqlList(String listStr) {
        List<String> result = new ArrayList<>();
        listStr = listStr.trim();
        if (listStr.isEmpty()) return result;

        int start = 0;
        int depth = 0;
        char quoteChar = '\0';
        boolean inQuote = false;

        for (int i = 0; i < listStr.length(); i++) {
            char c = listStr.charAt(i);

            // 处理引号
            if (c == '\'' || c == '"') {
                if (!inQuote) {
                    inQuote = true;
                    quoteChar = c;
                } else if (c == quoteChar) {
                    // 检查是否是转义的引号
                    int escapeCount = 0;
                    int j = i - 1;
                    while (j >= 0 && listStr.charAt(j) == '\\') {
                        escapeCount++;
                        j--;
                    }
                    if (escapeCount % 2 == 0) {
                        inQuote = false;
                    }
                }
            }

            // 只在不在引号内时处理括号
            if (!inQuote) {
                if (c == '(') depth++;
                else if (c == ')') depth--;
            }

            // 只在不在引号内且括号深度为0时处理逗号
            if (!inQuote && c == ',' && depth == 0) {
                result.add(listStr.substring(start, i).trim());
                start = i + 1;
            }
        }
        result.add(listStr.substring(start).trim());
        return result;
    }

    

    public static void main(String[] args) {

        String sql = "INSERT INTO table(c1,c2) values('1',0)";

        // 待删除字段(可替换为你想删除的字段)
        List<String> columnsToRemove = Arrays.asList(
                "c1"
        );

        String newSql = insertSqlUpdate(sql, columnsToRemove);
        System.out.println("优化后的 SQL:\n" + newSql);


    }
}

参考资料

posted @ 2025-07-19 20:59  向着朝阳  阅读(13)  评论(0)    收藏  举报