SSDT 不考虑触发 enable/disable 属性
SSDT does not consider trigger enable/disable property
我已经从现有数据库创建了一个 SSDT 项目。它在 tablename.sql 文件中包含现有触发器。
CREATE TABLE [dbo].[TableName] (
[ID] INT NULL
)
GO
CREATE TRIGGER trgTableName ON dbo.TableName
FOR INSERT
AS
BEGIN
....
END
GO
DISABLE TRIGGER [dbo].[trgTableName] ON [dbo].[TableName]; /* My trigger is currently disabled */
GO
但是,每当我修改触发器时,SSDT 都会再次启用它。部署时不考虑触发器禁用 属性。
有没有办法让 SSDT 禁用触发器(如果它已经在数据库上被禁用)?
我考虑的方法之一是添加为 post 部署脚本。但是,最好为此使用现有的 SSDT 功能,而不是手动添加 post 部署脚本。
编辑:看起来 SQL 服务器在我们更新它们时会自动启用触发器。在我的例子中,触发器有一个更新,因此它启用了触发器。但是,SSDT 不会在更新后禁用它。
一种方法当然是将其移动到 PostDeploy。但我建议创建一个单一的存储过程:
CREATE PROCEDURE mysp_disable_triggers
AS
BEGIN
DISABLE TRIGGER [dbo].[trgTableName] ON [dbo].[TableName];
END;
并在 post 部署脚本中调用它:
EXEC mysp_disable_triggers;
这样您就有了一个参考点并且您的代码仍然经过验证(检查参考是否存在并且它是正确的 SQL 代码)。
要检查的第二种方法是使用 ALTER TABLE
语法:
CREATE TABLE [dbo].[TableName](...);
GO
CREATE TRIGGER [dbo].[trgTableName] ...;
GO
ALTER TABLE [dbo].[trgTableName] DISABLE TRIGGER [dbo].[TableName];
编辑:它不会改变行为。所以PostDeploy方法似乎是可行的选择。
如果您有一个难以管理的大型数据库并且有很多此类内容,您可能会变得棘手并创建一个过程来编写一个过程来捕获触发器的状态并恢复它们。您可以 运行 PreDeploy 中的过程,然后 运行 PostDeploy 中生成的过程。像这样:
create procedure dbo.scriptResetDisableTriggers as
begin
set nocount on
declare
@sql nvarchar( max ),
@n nvarchar( 2 ) = nchar(0x0d) + nchar(0x0a)
select @sql =
N'create procedure dbo.resetDisabledTriggers as' + @n +
N'begin' + @n +
N' set nocount on' + @n + @n;
select @sql +=
N' begin try' + @n +
N' disable trigger ' + tr.name + N' on table ' + s.name + N'.' + t.name + @n +
N' end try' + @n +
N' begin catch' + @n +
N' print( error_message( ) ) -- or something else cool' + @n +
N' end catch' + @n + @n
from
sys.triggers tr
inner join
sys.tables t
on
tr.parent_id = t.object_id
inner join
sys.schemas s
on
t.schema_id = s.schema_id
where
tr.is_disabled = 1
select @sql +=
@n + N' drop procedure dbo.resetDisabledTriggers' + @n +
@n + N'end' + @n
print ( @sql )
execute sp_executesql @sql
end
我已经从现有数据库创建了一个 SSDT 项目。它在 tablename.sql 文件中包含现有触发器。
CREATE TABLE [dbo].[TableName] (
[ID] INT NULL
)
GO
CREATE TRIGGER trgTableName ON dbo.TableName
FOR INSERT
AS
BEGIN
....
END
GO
DISABLE TRIGGER [dbo].[trgTableName] ON [dbo].[TableName]; /* My trigger is currently disabled */
GO
但是,每当我修改触发器时,SSDT 都会再次启用它。部署时不考虑触发器禁用 属性。
有没有办法让 SSDT 禁用触发器(如果它已经在数据库上被禁用)?
我考虑的方法之一是添加为 post 部署脚本。但是,最好为此使用现有的 SSDT 功能,而不是手动添加 post 部署脚本。
编辑:看起来 SQL 服务器在我们更新它们时会自动启用触发器。在我的例子中,触发器有一个更新,因此它启用了触发器。但是,SSDT 不会在更新后禁用它。
一种方法当然是将其移动到 PostDeploy。但我建议创建一个单一的存储过程:
CREATE PROCEDURE mysp_disable_triggers
AS
BEGIN
DISABLE TRIGGER [dbo].[trgTableName] ON [dbo].[TableName];
END;
并在 post 部署脚本中调用它:
EXEC mysp_disable_triggers;
这样您就有了一个参考点并且您的代码仍然经过验证(检查参考是否存在并且它是正确的 SQL 代码)。
要检查的第二种方法是使用 ALTER TABLE
语法:
CREATE TABLE [dbo].[TableName](...);
GO
CREATE TRIGGER [dbo].[trgTableName] ...;
GO
ALTER TABLE [dbo].[trgTableName] DISABLE TRIGGER [dbo].[TableName];
编辑:它不会改变行为。所以PostDeploy方法似乎是可行的选择。
如果您有一个难以管理的大型数据库并且有很多此类内容,您可能会变得棘手并创建一个过程来编写一个过程来捕获触发器的状态并恢复它们。您可以 运行 PreDeploy 中的过程,然后 运行 PostDeploy 中生成的过程。像这样:
create procedure dbo.scriptResetDisableTriggers as
begin
set nocount on
declare
@sql nvarchar( max ),
@n nvarchar( 2 ) = nchar(0x0d) + nchar(0x0a)
select @sql =
N'create procedure dbo.resetDisabledTriggers as' + @n +
N'begin' + @n +
N' set nocount on' + @n + @n;
select @sql +=
N' begin try' + @n +
N' disable trigger ' + tr.name + N' on table ' + s.name + N'.' + t.name + @n +
N' end try' + @n +
N' begin catch' + @n +
N' print( error_message( ) ) -- or something else cool' + @n +
N' end catch' + @n + @n
from
sys.triggers tr
inner join
sys.tables t
on
tr.parent_id = t.object_id
inner join
sys.schemas s
on
t.schema_id = s.schema_id
where
tr.is_disabled = 1
select @sql +=
@n + N' drop procedure dbo.resetDisabledTriggers' + @n +
@n + N'end' + @n
print ( @sql )
execute sp_executesql @sql
end