sql - 如何忽略 IF EXISTS 块中的 GO 语句?
问题描述
我正在尝试根据 IF NOT EXISTS 条件执行脚本。但是,即使 IF NOT EXISTS 返回 1,BEGIN 和 END 中的块也会被执行。我无法更改 BEGIN 和 END 块中的语句。如何处理这种情况?
IF NOT EXISTS(SELECT 1 FROM [dbo].[UPGRADEHISTORY] WHERE SCRIPTNAME='001-MarkSubmitted.sql' AND RELEASENUMBER= '1')
BEGIN
IF NOT EXISTS(SELECT 1 FROM [dbo].[Action] WHERE Name='mark As Submitted')
BEGIN
SET IDENTITY_INSERT [dbo].[Action] ON
INSERT INTO [dbo].[Action](Id,Name,CreatedBy,CreatedOn) VALUES (6,'mark As Submitted',1,getdate())
SET IDENTITY_INSERT [dbo].[Action] OFF
END
GO
INSERT INTO [dbo].[StatusActionMapping](ArtifactType,StatusId,ActionId,RoleId) VALUES ('Report',11,6,1)
GO
INSERT INTO [dbo].[UpgradeHistory] ([ReleaseNumber],[ScriptNumber],[ScriptName],[ExecutionDate]) VALUES (1, (SELECT FORMAT(MAX(SCRIPTNUMBER) + 1, 'd3') FROM UpgradeHistory WHERE ReleaseNumber= 1),'001-MarkSubmitted.sql',GETDATE());
END
GO
解决方案
正如我在评论中提到的,GO
它不是Transact-SQL 运算符,它被您的 IDE/CLI 解释为批处理分隔符。SQL Server 实用程序语句 - GO:
SQL Server 提供的命令不是 Transact-SQL 语句,但可以被 sqlcmd 和 osql 实用程序以及 SQL Server Management Studio 代码编辑器识别。这些命令可用于促进批处理和脚本的可读性和执行。
GO 向 SQL Server 实用程序发出一批 Transact-SQL 语句结束的信号。
答案很简单,去掉GO
s。这里不需要它们;这是因为它们在那里,您会收到错误消息,因为将语句分成不同的批次在这里没有意义。你所拥有的相当于拥有以下 3 个“文件”并尝试独立运行它们:
文件 1:
IF NOT EXISTS(SELECT 1 FROM [dbo].[UPGRADEHISTORY] WHERE SCRIPTNAME='001-MarkSubmitted.sql' AND RELEASENUMBER= '1')
BEGIN
IF NOT EXISTS(SELECT 1 FROM [dbo].[Action] WHERE Name='mark As Submitted')
BEGIN
SET IDENTITY_INSERT [dbo].[Action] ON
INSERT INTO [dbo].[Action](Id,Name,CreatedBy,CreatedOn) VALUES (6,'mark As Submitted',1,getdate())
SET IDENTITY_INSERT [dbo].[Action] OFF
END
由于没有BEGIN
out会出错END
。
文件 2:
INSERT INTO [dbo].[StatusActionMapping](ArtifactType,StatusId,ActionId,RoleId) VALUES ('Report',11,6,1)
这会运行良好。
文件 3:
INSERT INTO [dbo].[UpgradeHistory] ([ReleaseNumber],[ScriptNumber],[ScriptName],[ExecutionDate]) VALUES (1, (SELECT FORMAT(MAX(SCRIPTNUMBER) + 1, 'd3') FROM UpgradeHistory WHERE ReleaseNumber= 1),'001-MarkSubmitted.sql',GETDATE());
END
由于END
没有BEGIN
.
您的查询中没有任何内容会导致解析错误,例如您将新列添加到现有表并稍后在批处理中引用它,因此无需分隔批处理。只需删除GO
s 中间的BEGIN...END
s 即可按您的要求工作:
IF NOT EXISTS (SELECT 1
FROM [dbo].[UPGRADEHISTORY]
WHERE SCRIPTNAME = '001-MarkSubmitted.sql'
AND RELEASENUMBER = '1')
BEGIN
IF NOT EXISTS (SELECT 1
FROM [dbo].[Action]
WHERE Name = 'mark As Submitted')
BEGIN
SET IDENTITY_INSERT [dbo].[Action] ON;
INSERT INTO [dbo].[Action] (Id, Name, CreatedBy, CreatedOn)
VALUES (6, 'mark As Submitted', 1, GETDATE());
SET IDENTITY_INSERT [dbo].[Action] OFF;
END;
INSERT INTO [dbo].[StatusActionMapping] (ArtifactType, StatusId, ActionId, RoleId)
VALUES ('Report', 11, 6, 1);
INSERT INTO [dbo].[UpgradeHistory] ([ReleaseNumber], [ScriptNumber], [ScriptName], [ExecutionDate])
VALUES (1, (SELECT FORMAT(MAX(SCRIPTNUMBER) + 1, 'd3') --This is a REALLY bad idea. Use an IDENTITY or SEQUENCE
FROM UpgradeHistory
WHERE ReleaseNumber = 1), '001-MarkSubmitted.sql', GETDATE());
END;
GO
还要注意我对你的最终观点INSERT
。最终会出现竞争FORMAT(MAX(SCRIPTNUMBER) + 1, 'd3')
条件。使用IDENTITY
或SEQUENCE
。
推荐阅读
- r - 根据 2 列中的值 + 模糊匹配对表进行重复数据删除
- java - Java中的随机,重复相同的数字
- wordpress - SCSS 的 PhpStorm 文件观察器未编译 node_modules
- javascript - 如何在 vuejs 中获取特定的对象值?
- javascript - 在 const = require 中显示文件结构的正确方法?
- python-2.7 - 如何在 python 2.7 中执行我的程序逻辑之前响应 HTTP 请求
- c - Gtk-CRITICAL **: 16:04:21.737: gtk_box_pack: 断言 'GTK_IS_WIDGET (child)' 失败
- yocto - 如何将 ldd 实用程序添加到 bitbake 图像
- javascript - 如何将具有特定键、深度键的 JSON 对象中的所有值放入数组中
- php - 返回 JSON 响应而不是 401 Blade 文件