我正在使用Regex.Split在关键字“GO”上拆分SQL脚本。我的问题是,我似乎无法理解如何让正则表达式进行拆分。我的正则表达式也在“GO”上分裂,即使它在SQL语句中也是如此:
Insert into x(a,b) values(‘please go get some text’,’abc’)
但我只想把它分成关键字“GO”。有什么建议吗?
编辑:我正在使用c#。目前我的正则表达式只是: foreach (string batch in Regex.Split(script, "\\bGO\\b", RegexOptions.IgnoreCase))
{
yield return batch;
}
答案 0 :(得分:4)
如果没有以真正正确的方式实现完整的SQL解析器(您可能不想这样做),这几乎是不可能的。
另一种方法是诉诸某些黑客攻击(即忽略引号内的文本部分),但如果您的SQL在某个其他位置包含文本“GO
”,则仍然无效。 'SELECT * FROM GO
'。
答案 1 :(得分:4)
在GO上自行拆分,例如:
foreach (string batch in Regex.Split(script, "^GO$\\n", RegexOptions.IgnoreCase | RegexOptions.Multiline))
{
yield return batch;
}
根据脚本的来源,您可能需要将其更改为“^ GO $ \\ r \\ n”
答案 2 :(得分:3)
您可以单独搜索“go”。不保证始终有效,但更有可能发挥作用。
答案 3 :(得分:2)
您可以尝试类似
的内容/; \ S GO \ S ; / I
如果你只是在一行中,你将会独立地覆盖每个GO句子(即其他行中的分号)。
如果您使用查询进一步执行,您可能希望将分号添加回每个查询。
警告如果发生“; GO;”发生在插入字符串中,如果没有正确的SQL解析器,就无法实现目标。
答案 4 :(得分:0)
以下是我用正则表达式解决这个问题的方法。
var statements = Regex.Split(sql, @"^\s*GO\s*$",
RegexOptions.IgnoreCase | RegexOptions.Multiline);
当它在它自己的行上时,它会在“GO”上分裂,并且可选地由空格包围。这些似乎是SSMS强制执行的规则 - 将GO
放在与任何其他语句一行的行上会导致错误(分号或否)。
请注意,如果您的脚本在块注释中拥有自己的GO语句,它仍然会中断。这是我能想到的唯一错误。
防弹解决方案是使用SMO,详见本answer。