如何在不执行脚本的情况下在SQL脚本上测试SQLCMD

时间:2016-10-20 15:20:45

标签: sql-server powershell sqlcmd

我有一个SQLCMD语法的大型SQL脚本存储库。每个脚本都定义了0个或更多$(SomeParam)个。我们有一个实用程序,它执行脚本并传递$(params)的值,实质上使我们能够为各种数据模型配置和自动化构建。

有时我们的构建过程失败,因为脚本指定了$(param),但未在我们的实用程序中配置。即我们对此$(param)

没有任何价值

我想在执行这些脚本之前执行这些脚本的测试运行。测试运行应确保已将所有必需的$(params)提供给脚本。不应该执行SQL本身 - 我只想知道它是否可编译。是否可以使用sqlcmd实现?

考虑的替代方案

我已经考虑过使用Powershell脚本查找文件中所有$(param)的匹配项(使用RegEx)并将其与实用程序中的params列表进行交叉检查。我希望尽可能在sqlcmd命令行或SQL脚本中保留所有功能。

2 个答案:

答案 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)

您可以创建脚本的副本,将脚本的执行自动封装到事务中,并在脚本结尾处引入错误。它总是打印错误。如果错误是您引入的错误,则脚本运行完美,否则打印参数错误。对不起我的英文