You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则表达式拆分SQL代码为符合SQL Server要求的多执行批次

SQL Server 批处理SQL智能拆分正则方案

核心需求适配

要解决的问题包括:

  • 跳过字符串字面量(单引号包裹)中的分号,避免错误拆分
  • 将CREATE PROCEDURE/ALTER PROCEDURE语句单独作为独立批处理(符合SQL Server要求)
  • 其他常规SQL语句按分号正常拆分

正则表达式实现

(?x)
(?:^|;\s*)
(?!\s*(CREATE|ALTER)\s+PROCEDURE)
(?:
    (?:[^';]+|'[^']*(?:''[^']*)*')+
)
|
\s*(CREATE|ALTER)\s+PROCEDURE\s+[^;]+;?

正则逻辑解释

  • (?x):开启忽略空白模式,让正则结构更清晰,不影响匹配逻辑
  • (?:^|;\s*):匹配批处理的起始位置——要么是SQL文本开头,要么是分号加任意空白字符
  • (?!\s*(CREATE|ALTER)\s+PROCEDURE):负前瞻断言,确保当前位置不是存储过程定义的开头
  • (?:[^';]+|'[^']*(?:''[^']*)*')+:匹配常规SQL语句内容,处理单引号字符串(包括SQL Server的转义单引号''),跳过字符串内的分号
  • |:分支匹配,专门捕获存储过程定义
  • \s*(CREATE|ALTER)\s+PROCEDURE\s+[^;]+;?:匹配完整的存储过程定义,从关键字开始到末尾分号(允许存储过程末尾无分号)

Java 代码示例

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.List;

public class SqlServerBatchSplitter {
    public static List<String> splitSqlBatches(String sqlContent) {
        List<String> batches = new ArrayList<>();
        String splitRegex = "(?x)(?:^|;\\s*)(?!\\s*(CREATE|ALTER)\\s+PROCEDURE)(?:(?:[^';]+|'[^']*(?:''[^']*)*')+)|\\s*(CREATE|ALTER)\\s+PROCEDURE\\s+[^;]+;?";
        Pattern pattern = Pattern.compile(splitRegex);
        Matcher matcher = pattern.matcher(sqlContent);

        while (matcher.find()) {
            String batch = matcher.group().trim();
            if (!batch.isEmpty()) {
                batches.add(batch);
            }
        }
        return batches;
    }

    public static void main(String[] args) {
        String sampleSql = "INSERT INTO Table1 VALUES ('test;1');\nINSERT INTO Table2 VALUES ('abc');\nCREATE PROCEDURE dbo.TestProc\nAS\nBEGIN\n    SELECT * FROM Table1;\nEND;\nINSERT INTO Table3 VALUES ('xyz');\nEXEC dbo.TestProc;";
        List<String> result = splitSqlBatches(sampleSql);

        for (int i = 0; i < result.size(); i++) {
            System.out.printf("=== 批次 %d ===\n%s\n", i+1, result.get(i));
        }
    }
}

额外说明

  • 该正则已适配SQL Server的单引号转义规则,不会误拆分字符串内的分号
  • 存储过程定义内部的分号不会触发拆分,确保存储过程作为单个批处理提交
  • 如果需要支持SQL Server常用的GO批处理分隔符,可以在正则中添加对应分支,比如在起始匹配部分加入(?:^|;\s*|\bGO\b\s*)

内容的提问来源于stack exchange,提问作者Mikhail T.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 07:52:45