作为我的集成策略的一部分,我有一些SQL脚本运行以更新数据库.所有这些脚本做的第一件事就是检查它们是否需要运行,例如:
if @version <> @expects begin declare @error varchar(100); set @error = 'Invalid version. Your version is ' + convert(varchar, @version) + '. This script expects version ' + convert(varchar, @expects) + '.'; raiserror(@error, 10, 1); end else begin ...sql statements here... end
效果很好!除非我需要添加存储过程."create proc"命令必须是一批sql命令中的唯一命令.在我的IF语句中放入"create proc"会导致此错误:
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
哎哟! 如何将CREATE PROC命令放在我的脚本中,并让它只在需要时执行?
这是我想出的:
将它包装在EXEC()中,如下所示:
if @version <> @expects begin ...snip... end else begin exec('CREATE PROC MyProc AS SELECT ''Victory!'''); end
奇迹般有效!
SET NOEXEC ON是关闭部分代码的好方法
IF NOT EXISTS (SELECT * FROM sys.assemblies WHERE name = 'SQL_CLR_Functions') SET NOEXEC ON GO CREATE FUNCTION dbo.CLR_CharList_Split(@list nvarchar(MAX), @delim nchar(1) = N',') RETURNS TABLE (str nvarchar(4000)) AS EXTERNAL NAME SQL_CLR_Functions.[Granite.SQL.CLR.Functions].CLR_CharList_Split GO SET NOEXEC OFF
这里找到: https://codereview.stackexchange.com/questions/10490/conditional-create-must-be-the-only-statement-in-the-batch
PS另一种方式是SET PARSEONLY {ON | 关闭}.
但请注意您的存储过程中的单引号 - 它们需要通过添加第二个来"转义".第一个答案是这样做的,但万一你错过了.年轻球员的陷阱.