2

我正在尝试在迁移我的数据库时将一批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”附近的语法不正确

仅发送第一个触发器时工作正常。不知道出了什么问题。

4

3 回答 3

3

根据有关批次的文档,您不能将多个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.js 创建并执行一个数据库创建脚本。

一种解决方案是采用与 SQL Server 工具相同的方法:生成单独的批次并针对数据库逐一执行它们。

另一种选择是创建带有GO分隔符的单个 SQL 脚本,并使用 SQL Server 的命令行工具执行它。这更易于维护,因为您可以保存脚本并对其进行版本控制、检测更改等。

第三种选择是使用 SQL Server 的开发工具来为您的数据库建模。数据库项目支持版本控制和验证。主要优点是 SSDT 可以生成脚本来更新目标数据库,类似于 Redgate 的工具。SSDT 相当聪明,可以识别在工具本身内部执行的重命名等,并使用例如sp_rename而不是删除一列并创建新列。

另一个优点是 SSDT 生成一个dacpac,本质上是一个编译模型,可用于比较目标数据库并生成更新脚本。

这使得连续数据库部署变得更加容易。它由AppVeyorTFS支持。TeamCity和任何可以运行sqlpackage工具的工具/服务。

缺点是 SSDT 仅适用于 SQL Server 数据库。

于 2016-11-30T12:24:55.570 回答
1

对于任何想要执行此操作的人来说GO,运行多个批处理并不总是一个好的解决方案,因为它不是 T-SQL,它只有 SSMS 和一些命令行工具才能理解。例如,您不能在存储过程或函数中使用它。

这是否意味着存储过程和函数仅限于单个批次?

除了会议厅的静默声调之外,很少有人提到它,但实际上您可以在一个保证在任何地方工作的 T-SQL 脚本中运行多个批处理。动态 SQL。EXEC sp_executesql @sql始终在自己的批次中运行。如果需要,您还可以使用事务围绕多个EXEC sp_executesql调用。动态 SQL 编写起来很痛苦,但它可以让你在一个存储过程中执行多个批处理之类的事情,否则这是不可能的。

于 2021-01-07T16:20:13.370 回答
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)
于 2016-11-30T11:39:45.020 回答