我有一个SQLCMD语法的大型SQL脚本存储库。每个脚本都定义了0个或更多$(SomeParam)
个。我们有一个实用程序,它执行脚本并传递$(params)
的值,实质上使我们能够为各种数据模型配置和自动化构建。
有时我们的构建过程失败,因为脚本指定了$(param)
,但未在我们的实用程序中配置。即我们对此$(param)
集
我想在执行这些脚本之前执行这些脚本的测试运行。测试运行应确保已将所有必需的$(params)
提供给脚本。不应该执行SQL本身 - 我只想知道它是否可编译。是否可以使用sqlcmd实现?
考虑的替代方案
我已经考虑过使用Powershell脚本查找文件中所有$(param)
的匹配项(使用RegEx)并将其与实用程序中的params列表进行交叉检查。我希望尽可能在sqlcmd命令行或SQL脚本中保留所有功能。
答案 0 :(得分:3)
SET NOEXEC ON
使SQL Server进入一种模式,其中语句被解析和编译但不执行,但命令SET NOEXEC OFF
除外,它将事物恢复到原始状态。因此,如果语句由于缺少参数而在语法上无效,SET NOEXEC ON
将捕获它。
SET NOEXEC ON
有一个重要的限制。该文档误导性地指出“此设置对于SQL Server在执行时验证Transact-SQL代码中的语法和对象名称非常有用”,但事实上,在SET NOEXEC ON
下,SQL Server不会将名称解析为大多数对象一点都不以下脚本将无错误地解析:
SET NOEXEC ON;
GO
CREATE TABLE Foo(ID INT PRIMARY KEY);
GO
INSERT Fooo(ID) VALUES (5); -- Oops, typo
这并不意味着根本没有解决任何名称。以下脚本仍将失败:
SET NOEXEC OFF;
GO
CREATE FUNCTION Foo() RETURNS TABLE AS RETURN (SELECT 0 Bar);
GO
SET NOEXEC ON;
GO
SELECT dbo.Foo(); -- No error here, even though Foo can't be invoked this way
SELECT * FROM dbo.Foo(5); -- Error here: too many arguments specified
你可能会说,但是:
SET NOEXEC ON;
GO
CREATE FUNCTION Foo() RETURNS TABLE AS RETURN (SELECT 0 Bar);
GO
SELECT * FROM dbo.Foo(5); -- No error, because Foo doesn't exist
所以SET NOEXEC ON
既不能作为保证脚本完全有效的方法,也不能作为确定脚本绝对无效的方法。只要你意识到它的局限性,它仍然有用。
对于对象名称,执行的另一个设置始终如一:SET PARSEONLY ON
。这不仅不执行语句,甚至不编译它们。上面给出NOEXEC
错误的示例不会导致PARSEONLY
出错。如下所示:
CREATE TYPE MyInt FROM INT;
GO
CREATE TABLE A(ID MyInt);
-- Error under NOEXEC since MyInt does not exist, no error under PARSEONLY
因此,如果您只想检查语法有效性,PARSEONLY
优于NOEXEC
。
答案 1 :(得分:0)
您可以创建脚本的副本,将脚本的执行自动封装到事务中,并在脚本结尾处引入错误。它总是打印错误。如果错误是您引入的错误,则脚本运行完美,否则打印参数错误。对不起我的英文