SQL 触发器不起作用

发布于 2024-10-19 08:33:58 字数 487 浏览 4 评论 0原文

是否存在不触发触发器的条件?

我们有这样的情况:

我们有一个表,并且有一些行被删除。我们需要知道谁和/或何时删除这些行。

我们创建这个触发器:

ALTER TRIGGER [dbo].[AUDITdel_nit] ON [dbo].[Client]
 FOR DELETE
 AS
 Insert into AUDIT select 'Delete', getdate(), 'Row Deleted', SYSTEM_USER, host_name(),
 (select 'ID Client: ' + convert(varchar(12),Id)  from deleted), 'Client' ,APP_NAME()

我们做了一些测试:通过存储过程删除行,删除的行出现在我们的 AUDIT 表中。

但今天突然我们发现删除了一行,但该行没有出现在 AUDIT 表中......

知道可能出了什么问题吗?

Are there any conditions in which a Trigger is not fired?

We have this situation:

We have a table and there are rows that are been deleted. We need to know who and/or when these row are deleted.

We create this trigger:

ALTER TRIGGER [dbo].[AUDITdel_nit] ON [dbo].[Client]
 FOR DELETE
 AS
 Insert into AUDIT select 'Delete', getdate(), 'Row Deleted', SYSTEM_USER, host_name(),
 (select 'ID Client: ' + convert(varchar(12),Id)  from deleted), 'Client' ,APP_NAME()

We made some test: deleting rows via stored procedures and the deleted rows appears in our AUDIT table.

But suddenly today we found a row deleted that does not appear in the AUDIT table...

Any idea what could be wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冬天旳寂寞 2024-10-26 08:33:58

您需要使其处理当前无法执行的多个记录删除。假设将删除、插入或更新多个记录,则必须始终编写所有触发器。

ALTER TRIGGER [dbo].[AUDITdel_nit] ON [dbo].[Client]  
FOR DELETE  AS  

INSERT INTO AUDIT 
SELECT 'Delete', getdate(), 'Row Deleted', SYSTEM_USER, host_name(),  
         'ID Client: ' + convert(varchar(12),Id) , 'Client' ,APP_NAME() 
FROM DELETED

批量插入还可以绕过触发器,并且截断表不涉及触发器,因为未记录操作,但我认为这些不是您的问题。还可以运行 Openrowset 语句来忽略触发器。您可以在代码中搜索此短语以查看进程是否正在执行此操作:WITH(IGNORE_TRIGGERS)。您还可以专门禁用和重新启用触发器,但除了 dbas 之外,生产中的任何人都不应有权执行此操作。如果每个人都拥有这些权利,那么您需要尽快解决该问题。

You need to make it handle multiple record deletes which it currently cannot do. All triggers must always be written assuming that multiple records will be deleted, inserted or updated.

ALTER TRIGGER [dbo].[AUDITdel_nit] ON [dbo].[Client]  
FOR DELETE  AS  

INSERT INTO AUDIT 
SELECT 'Delete', getdate(), 'Row Deleted', SYSTEM_USER, host_name(),  
         'ID Client: ' + convert(varchar(12),Id) , 'Client' ,APP_NAME() 
FROM DELETED

Bulk inserts can also bypass a trigger and truncate table does not involve triggers as the actions aren't logged, but I think these are not your issue here. Openrowset statements can also be run to ignore triggers. You can search your code for this phrase to see if a process is doing that: WITH(IGNORE_TRIGGERS). You can also specifically disable and re-enable a trigger but no one on production should have the rights to do that except dbas. If everyone has those rights, you need to fix that ASAP.

旧街凉风 2024-10-26 08:33:58

你能检查一下你的触发器是否没有失效吗?

SELECT * FROM   ALL_OBJECTS WHERE  OBJECT_NAME = 'your_trigger' AND OBJECT_TYPE = 'TRIGGER' AND STATUS <> 'VALID'

Can you check if your trigger is not invalidated ?

SELECT * FROM   ALL_OBJECTS WHERE  OBJECT_NAME = 'your_trigger' AND OBJECT_TYPE = 'TRIGGER' AND STATUS <> 'VALID'
绳情 2024-10-26 08:33:58

我认为删除后插入语句不起作用。这样您就可以检查审计插入失败的原因。

Insert into AUDIT select 'Delete', getdate(), 'Row Deleted', SYSTEM_USER, host_name(),
(select 'ID Client: ' + convert(varchar(12),Id)  from deleted), 'Client' ,APP_NAME()

I think insert statement after deletion didn't work. So you can check why the audit insert fails.

Insert into AUDIT select 'Delete', getdate(), 'Row Deleted', SYSTEM_USER, host_name(),
(select 'ID Client: ' + convert(varchar(12),Id)  from deleted), 'Client' ,APP_NAME()
霊感 2024-10-26 08:33:58

由于您使用的是触发器,是否有可能对客户端表进行的某些更改是由其他触发器引起的,并且嵌套触发器选项设置为 0?这不是默认设置,但在这种情况下会导致触发器不触发。效果演示如下。要查看是否已设置此选项,只需运行不带参数的 sp_configure,然后找到 nested triggers 行。

sp_configure 'nested triggers','0'
go
reconfigure
go
create table T3 (
    ID int not null
)
go
create table T2 (
    ID int not null
)
go
create trigger T_T2
on T2
for insert
as
    insert into T3(ID) select ID from inserted
go
create table T1 (
    ID int not null
)
go
create trigger T_T1
on T1
for insert
as
    insert into T2(ID) select ID from inserted
go
insert into T1(ID)
select 1
go
select * from T1
select * from T2
select * from T3

消息&结果:

Configuration option 'nested triggers' changed from 1 to 0. Run the RECONFIGURE statement to install.

(1 row(s) affected)

ID
----
1
(1 row(s) affected)

ID
----
1
(1 row(s) affected)

ID
----
(0 row(s) affected)

Since you're using triggers, is there a possibility that some changes to the clients table are caused by other triggers, and the nested triggers option is set to 0? This isn't the default setup, but it would result in your trigger not firing in this case. A demonstration of the effect is below. To see whether this option has been set, just run sp_configure with no parameters, and find the nested triggers row.

sp_configure 'nested triggers','0'
go
reconfigure
go
create table T3 (
    ID int not null
)
go
create table T2 (
    ID int not null
)
go
create trigger T_T2
on T2
for insert
as
    insert into T3(ID) select ID from inserted
go
create table T1 (
    ID int not null
)
go
create trigger T_T1
on T1
for insert
as
    insert into T2(ID) select ID from inserted
go
insert into T1(ID)
select 1
go
select * from T1
select * from T2
select * from T3

Messages & Results:

Configuration option 'nested triggers' changed from 1 to 0. Run the RECONFIGURE statement to install.

(1 row(s) affected)

ID
----
1
(1 row(s) affected)

ID
----
1
(1 row(s) affected)

ID
----
(0 row(s) affected)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文