我正在研究基于Java的OSS应用程序SqlHawk,其功能之一是针对服务器运行升级sql脚本。
Microsoft已经将使用GO语句将脚本拆分为批处理,这是个好主意,但只是要求对字符串进行错误匹配。
目前我有一个非常简陋的话:
// split where GO on its own on a line
Pattern batchSplitter = Pattern.compile("^GO", Pattern.MULTILINE);
...
String[] splitSql = batchSplitter.split(definition);
...
哪种作品很容易因quoted GO statements或缩进问题而被绊倒。
我认为让这个真正可靠的唯一方法是在应用程序中有一个SQL解析器,但我不知道如何解决这个问题,或者这实际上是否真的不太可靠(特别是考虑到这个工具支持)多个DBMS)。
我可以通过哪些方式解决此问题?代码示例对我来说非常有帮助。
github上的目前使用jtds执行脚本中的批处理。
答案 0 :(得分:1)
GO是客户端批处理分隔符命令。你可以用;替换它。它不应该在您的EXEC动态SQL中发送。
USE master
GO --<----- client actually send the first batch to SQL and wait for a response
SELECT * from sys.databases
GO
应翻译成
Application.Exec("USE master");
Application.Exec("SELECT * from sys.databases");
或者你可以这样写:
Application.Exec("'USE master;SELECT * from sys.databases")
更多关于GO的信息 http://msdn.microsoft.com/en-us/library/ms188037(v=sql.90).aspx
答案 1 :(得分:1)
好的,所以这不是完全你想要的,但你可能会发现它是一个开始。我发布了SchemaEngine(它构成了我的大多数产品的核心)作为开源here。在那里,你会发现C#代码可以非常可靠地完成你想要的东西(即不会绊倒字符串,注释等)。它还支持'GO x'语法重复批次x次。
如果您下载并查看/Atlantis.SchemaEngine/Helpers
,您会找到一个名为BatchParser.cs
的类,其中包含一个名为ParseBatches
的方法 - 它的功能几乎与它在锡上的内容相同