我正在尝试将一批CREATE TRIGGER
个语句作为要在迁移数据库时处理的字符串发送
CREATE TRIGGER [dbo].[triggerBar] ON [dbo].[tableBar]
INSTEAD OF UPDATE,INSERT AS
BEGIN
SET NOCOUNT ON
-- Trigger body here..
END;
CREATE TRIGGER [dbo].[triggerFoo] ON [dbo].[tableFoo]
INSTEAD OF UPDATE,INSERT AS
BEGIN
SET NOCOUNT ON
-- Trigger body here..
END;
所以我用;
分隔每个语句块但是我仍然遇到这个错误:
关键字“TRIGGER”附近的语法不正确
当只发送第一个触发器时工作正常。不确定是什么问题。
答案 0 :(得分:2)
根据documentation on batches,您不能在同一批次中放置多个CREATE TRIGGER
语句:
创建默认,创建功能,创建过程,创建规则,创建模式,创建触发器和创建视图语句不能与批处理中的其他语句组合。 CREATE语句必须启动批处理。该批次中的所有其他语句将被解释为第一个CREATE语句定义的一部分。
GO
有效,因为它是SSMS,sqlcmd和SQL Server开发工具识别的批处理分隔符,永远不会发送到服务器。该工具使用它来批量拆分文本并将它们逐个发送到服务器。事务跨批处理(毕竟它是相同的连接),因此可以回滚某些DDL语句。
我假设您要从Node创建并执行数据库创建脚本。
一种解决方案是采用与SQL Server工具相同的方法:生成单独的批处理并逐个对数据库执行。
另一种选择是使用GO
分隔符创建单个SQL脚本,并使用SQL Server的命令行工具执行它。这样更易于维护,因为您可以保存脚本并对其进行版本控制,检测更改等。
第三种选择是使用SQL Server的开发工具为数据库建模。数据库项目支持版本控制和验证。但主要的优点是SSDT可以生成一个脚本来更新目标数据库,类似于Redgate的工具。 SSDT具有中等智能,可以识别在工具本身内执行的重命名等,并使用例如sp_rename
而不是删除一列并创建一个新列。
另一个优点是SSDT生成dacpac
,本质上是一个已编译的模型,可用于对目标数据库进行差异化并生成更新脚本。
这使得连续数据库部署更容易批次。它由AppVeyor,TFS支持。 TeamCity以及可以运行sqlpackage工具的任何工具/服务。
缺点是SSDT仅适用于SQL Server数据库。
答案 1 :(得分:1)
对于任何希望做这个 - GO
并不总是运行多个批次,因为它不是T-SQL一个很好的解决方案,它只能通过SSMS和一些命令行工具的理解。例如,你不能在存储过程或函数中使用它。
这是否表示存储过程和函数被限制为单批?
它很少提到在会议室安静的音调之外,但实际上你可以说是保证在任何地方工作单的T-SQL脚本中运行多个批次。动态SQL。 EXEC sp_executesql @sql
始终在其自己的批次中运行。您可以进一步环绕多个EXEC sp_executesql
与交易电话,如果您需要。动态SQL是一个痛苦的写,但它可以让你做这样的事情在一个存储过程多批,否则是不可能的。
答案 2 :(得分:0)
某些陈述在它们之前没有任何内容。在这种情况下,在SSMS中,使用GO
来指示批处理的结束(这有效地清除了缓冲区,因此将清除在GO
之前声明的任何变量。)
如果你在SSMS,你可以:
CREATE TRIGGER ... AS ...
GO
CREATE TRIGGER ... etc
如果您不在SSMS之外,则必须发送单独的命令,或者将它们放入T-SQL中的字符串并执行字符串:
DECLARE @Trig1 NVARCHAR(MAX)
DECLARE @Trig2 NVARCHAR(MAX)
DECLARE @Trig3 NVARCHAR(MAX)
SET @Trig1 = 'CREATE TRIGGER ...'
SET @Trig2 = 'CREATE TRIGGER ...'
SET @Trig3 = 'CREATE TRIGGER ...'
EXEC (@Trig1)
EXEC (@Trig2)
EXEC (@Trig3)