分离批处理中运行的多个SQL Server语句
我试图发送一批CREATE TRIGGER
语句作为一个string来迁移我的数据库时进行处理
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”附近的语法错误
发送只是第一个触发器工作得很好。 不知道什么是错的。
根据批处理文档,不能在同一批次中放置多个CREATE TRIGGER
语句:
CREATE DEFAULT,CREATE FUNCTION,CREATE PROCEDURE,CREATE RULE,CREATE SCHEMA,CREATE TRIGGER和CREATE VIEW语句不能与批处理中的其他语句结合使用。 CREATE语句必须启动批处理。 在该批处理中的所有其他语句将被解释为第一个CREATE语句定义的一部分。
GO
可以工作,因为它是由SSMS,sqlcmd和SQL Server开发工具所识别的批处理定界符,绝不会发送到服务器。 该工具使用它来批量分割文本并将它们逐个发送到服务器。 事务跨批处理(毕竟是相同的连接),所以可以回滚某些DDL语句。
我假设你想从Node创build并执行一个数据库创build脚本。
一种解决方法是使用与SQL Server工具相同的方法:生成单独的批处理,并逐个针对数据库执行它们。
另一个select是使用GO
分隔符创build一个SQL脚本,并使用SQL Server的命令行工具执行它。 这是更可维护的,因为你可以保存和版本的脚本,检测到变化等
第三个选项是使用SQL Server的开发工具来build模您的数据库。 数据库项目支持版本控制和validation。 主要的好处是SSDT可以生成一个脚本来更新一个目标数据库,类似于Redgate的工具。 SSDT是相当聪明的,可以识别在工具本身内部执行的重命名等,使用例如sp_rename
而不是删除一列并创build一个新的。
另一个优点是SSDT生成一个dacpac
,本质上是一个编译模型,可以用来dacpac
目标数据库和生成更新脚本。
这使连续的数据库部署变得更容易。 它由AppVeyor , TFS支持。 TeamCity和任何可以运行sqlpackage工具的工具/服务。
缺点是SSDT只适用于SQL Server数据库。
某些陈述在他们面前什么也没有。 在这种情况下,在SSMS中,使用GO
来指示批次的结束(这将有效地清除缓冲区,所以在GO
之前声明的任何variables都将被清除)。
如果你在SSMS,你可以:
CREATE TRIGGER ... AS ... GO CREATE TRIGGER ... etc
如果你不在SSMS中,你必须发送单独的命令,或者把它们放到T-SQL的string中,然后执行string:
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)