在 SQL 查询代码中用于多行搜索和替换的正则表达式

RegEx for multiline search and replace in SQL query code

关于“使用正则表达式搜索和替换”的主题,Internet 上有很多合格的文档。其中只有少数展示了如何在多行上下文中执行此操作。更少的节目指示如何为其中的多个项目生成正则表达式。

我已经尝试了编辑器中的可安装 RegEx 工具(EditPad Pro、RJ TextED、EmEditor、Notepad++、Sublime Text 3、Visual Studio Professional 2019、最新的 JetBrains PHPstorm 版本等)和在线 RegEx 服务(regular expressions 101, RegExr) 一整天,阅读 Whosebug 上符合我的标题标准的答案,并尝试充分利用各种在线教程。

你说我笨,但我一直没能理解下面的概念是否可行

我要更改的 SQL 查询部分如下:

    AND op.OP1OPVerfahren > 0

    AND p.Testzwecke = 0

    AND NOT EXISTS (SELECT DISTINCT 1 FROM ods39.dat_optherapie op2 WHERE op2.patID = p.ID AND op2.revision > op.revision)

    UNION ALL

图例:

查询的 above-mentioned 部分具有相关的定量复杂性:在查询中,该段在以下变体中出现 780 次:

    AND **op.OP1OPVerfahren** _up_to_ **op.OP10OPVerfahren** > 0

    AND p.Testzwecke = 0

    AND NOT EXISTS (SELECT DISTINCT 1 FROM **ods01.dat_optherapie** _up_to_ **ods39.dat_optherapie** op2 WHERE op2.patID = p.ID AND op2.revision > op.revision)

    UNION ALL

为了完全理解我想在这里解决的问题,我想将 fore-mentioned 替换为:

    AND **op.OP1OPVerfahren** _up_to_ **op.OP10OPVerfahren** > 0

    AND p.Testzwecke = 0

    AND NOT EXISTS (SELECT DISTINCT 1 FROM **ods01.dat_optherapie** _up_to_ **ods39.dat_optherapie** op2 WHERE op2.patID = p.ID AND op2.revision > op.revision)

    GROUP BY **OP1OPVerfahren** _up_to_ **OP10OPVerfahren**

    UNION ALL

第一行的 op.OP_x_OPVerfahren (x = 1 到 10) 和 OP_x_OPVerfahren (x = 1 到 10) 在 GROUP BY 语句中在数值上彼此相关,i。 e.当我想将替换过程从 39 个数据库的 op.OP1OPVerfahren 更改为 39 个数据库的 op.OP2OPVerfahren 等等时,GROUP BY 数字应相应更改。

现在,对所有39个数据库进行这个替换。整个 SQL 查询代码大约有 20.000 行代码——我不想花几个小时手动替换的原因是不同文件中有更多这样的 SQL 查询结构需要在类似的文件中替换时尚

举个例子:

代码...

    AND op.OP1OPVerfahren > 0

    AND p.Testzwecke = 0

    AND NOT EXISTS (SELECT DISTINCT 1 FROM ods39.dat_optherapie op2 WHERE op2.patID = p.ID AND op2.revision > op.revision)

    UNION ALL

... 需要在 UNION ALL 之前用 GROUP BY OP1OPVerfahren 扩展 ods01ods39 的 39 个数据库。然后对相同的 39 个数据库再次使用 op.OP2OPVerfahrenOP2OPVerfahren,直到最终达到 (op.)OP10OPVerfahren(= 780 个替换)。

新插入的 GROUP BY 语句的 OP_x_... 计数应与 op.OP_x_... 编号相同。

我已经尝试了大量不同的正则表达式语句(例如 \d\d、(\d)(\d)、\d{2},以及许多其他根据 above-mentioned 编辑器),但我无法找到如何根据数据库中的“数字检测”进行“数字检测”(op.OP_x_OPVerfahrenOP_x_OPVerfahrenods_x_.dat_optherapie).

非常感谢您从您最宝贵的经验和专业知识中获得的一点帮助,我也非常感谢您收到除上述编辑之外的其他推荐(甚至可能是 testable) 正则表达式处理。

我相信类似以下正则表达式 find/replace 的表达式可以满足您的要求:

查找:

AND op.OP(\d{1,2})(OPVerfahren.*?\))

替换为:

AND op.OP \n GROUP BY OPOPVerfahren

请注意,它需要为正则表达式设置“全局”和“点匹配换行符”选项。

简要说明一下,这有 2 个捕获组,一个用于 op.OP 和 OPVerfahren 之间的数字,第二个用于捕获之后的所有内容,直到 "(SELECT DISTINCT... )。然后在正则表达式的替换部分将它们用作 $1 和 $2。

测试示例here。我相信这应该适用于 Notepad++。

(顺便说一句,我认为你的“GROUP BY OP1Verfahren”应该是“GROUP BY OP1OPVerfahren”对吗?即 2 手的“OP”!)

我们可以像这样使用正则表达式替换来完成这项工作:

(AND\ +op\.(OP\d0?OPVerfahren)\ *>\ *0\s+AND\ +p\.Testzwecke\ *=\ *0\s+AND\ +NOT\ +EXISTS\ *\(SELECT\ +DISTINCT\ +1\ +FROM\ +ods[0123][0-9]\.dat_optherapie\ +op2\ +WHERE\ +op2\.patID\ *=\ *p\.ID\ +AND\ +op2\.revision\ *>\ *op\.revision\))(\s+UNION\s+ALL)

Demo

它与原始字符串相当紧密,并且大多只引入 variable-length 白色 space 字符的量词。当存在 \ * 时,可能会出现可选的 space,如果 space 是强制性的,则使用 \ +。否则白色 space shorthand 字符 \s 不仅用于允许 spaces,还用于换行符等。要使其工作,请启用 s|singleline 标志(或在模式前面添加 (?s))。