在 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
图例:
op.OP1OPVerfahren
是第一次手术的数据库字段,可以记录10次手术(OP1OPVerfahren
直到OP10OPVerfahren
)
p.Testzwecke
是对患者个人数据的 JOIN,例如名字、姓氏等
ods39.dat_optherapie
是来自数据库 ods39
的 table dat_optherapie
- 系统由 50 个 MySQL 完全相同结构的数据库组成
p.ID
只是患者的ID
op.revision
是一个自动递增的跟踪器,用于保存同一外科手术的多少数据记录集(有时需要在精度意义上进行修改)
查询的 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
扩展 ods01
至 ods39
的 39 个数据库。然后对相同的 39 个数据库再次使用 op.OP2OPVerfahren
和 OP2OPVerfahren
,直到最终达到 (op.)OP10OPVerfahren
(= 780 个替换)。
新插入的 GROUP BY
语句的 OP_x_...
计数应与 op.OP_x_...
编号相同。
我已经尝试了大量不同的正则表达式语句(例如 \d\d、(\d)(\d)、\d{2},以及许多其他根据 above-mentioned 编辑器),但我无法找到如何根据数据库中的“数字检测”进行“数字检测”(op.OP_x_OPVerfahren
和 OP_x_OPVerfahren
)ods_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)
它与原始字符串相当紧密,并且大多只引入 variable-length 白色 space 字符的量词。当存在 \ *
时,可能会出现可选的 space,如果 space 是强制性的,则使用 \ +
。否则白色 space shorthand 字符 \s
不仅用于允许 spaces,还用于换行符等。要使其工作,请启用 s|singleline 标志(或在模式前面添加 (?s)
)。
关于“使用正则表达式搜索和替换”的主题,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
图例:
op.OP1OPVerfahren
是第一次手术的数据库字段,可以记录10次手术(OP1OPVerfahren
直到OP10OPVerfahren
)p.Testzwecke
是对患者个人数据的 JOIN,例如名字、姓氏等ods39.dat_optherapie
是来自数据库ods39
的 tabledat_optherapie
- 系统由 50 个 MySQL 完全相同结构的数据库组成p.ID
只是患者的IDop.revision
是一个自动递增的跟踪器,用于保存同一外科手术的多少数据记录集(有时需要在精度意义上进行修改)
查询的 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
扩展 ods01
至 ods39
的 39 个数据库。然后对相同的 39 个数据库再次使用 op.OP2OPVerfahren
和 OP2OPVerfahren
,直到最终达到 (op.)OP10OPVerfahren
(= 780 个替换)。
新插入的 GROUP BY
语句的 OP_x_...
计数应与 op.OP_x_...
编号相同。
我已经尝试了大量不同的正则表达式语句(例如 \d\d、(\d)(\d)、\d{2},以及许多其他根据 above-mentioned 编辑器),但我无法找到如何根据数据库中的“数字检测”进行“数字检测”(op.OP_x_OPVerfahren
和 OP_x_OPVerfahren
)ods_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)
它与原始字符串相当紧密,并且大多只引入 variable-length 白色 space 字符的量词。当存在 \ *
时,可能会出现可选的 space,如果 space 是强制性的,则使用 \ +
。否则白色 space shorthand 字符 \s
不仅用于允许 spaces,还用于换行符等。要使其工作,请启用 s|singleline 标志(或在模式前面添加 (?s)
)。