2

刚刚使用 SQL Server 和触发器经历了一些非常奇怪的事情(无论如何对我来说)。详细信息如下 - 不确定哪些是相关的,所以我只列出(如果我遗漏了什么,请询问):

  • 触发器类型:INSTEAD OF INSERT
  • 它是桌子上唯一的触发器
  • 有问题的数据库是复制的(从现有的数据库中),它触发器 - 我没有执行这个复制(所以我不知道用什么方法来做)。
  • 复制的数据库表现在具有带有约束的新列 - 大多数(如果不是全部)只是 NOT NULL
  • 直到我这样做之后,触发器才被改变 - 它没有考虑具有约束的新列

好的,所以这里是:似乎在我改变它之前从未调用过触发器并开始导致所有这些都是“预期行为”的问题,现在我可以看到发生了什么)。

  • 因为(新)DB 表具有具有 NOT NULL 约束的新列,并且原始触发器(INSERT)没有考虑到这一点,所以 INSERT按预期失败
  • 但是,在我更改触发器之前,插入成功!再次注意,这个触发器没有考虑到新列......即使我的 ALTER 仍然没有考虑到它们(我的错误) - 所以这并不是说我通过我的 ALTER 操作“纠正”了任何东西。然而,结果/行为的差异,之前(插入成功,这是意外的)和之后我的 ALTER TRIGGER(插入失败如预期)令人困惑......

我找不到任何资源表明ALTERING触发器将“启用它”——假设它被禁用——这是我能理解这一切的唯一方法......

所以似乎数据库复制(ing)与触发器有关?为什么触发器会(或者更确切地说会)ALTER突然使触发器恢复生机(没有明确ENABLE- ing)?

我绝不是 DBA 也不是 SQL 大师,所以如果很明显,我可以接受被置于耻辱殿堂......

4

1 回答 1

3

好吧,我在文档中也找不到它,但似乎ALTERing 触发器确实启用了它:

create table dbo.t (col1 int)
go

create trigger tr on dbo.t instead of insert as insert into dbo.t values(1)
go

disable trigger tr on dbo.t
go

-- returns 1
select is_disabled from sys.triggers where parent_id = object_id('dbo.t')
go

alter trigger tr on dbo.t instead of insert as insert into dbo.t values(2)
go

-- now returns 0
select is_disabled from sys.triggers where parent_id = object_id('dbo.t')
go

drop table dbo.t
go

我认为这可以解释您所看到的行为。如果我必须进行完整的猜测,我会说这是ALTER TRIGGER(事务)语法糖,因此触发器被重新启用,因为它实际上是重新创建的,但这纯粹是猜测。DROP TRIGGERCREATE TRIGGER

于 2013-06-06T19:20:14.667 回答