2013-03-13 57 views
3

我注意到了一个非常奇怪的行为。 如果我创建一个insert-select语句并且select部分不返回任何数据,那么插入部分仍然会执行,甚至插入触发器也会被调用(在插入触发器中,插入的pseudotable中有0行)。为什么在没有要插入的数据时调用插入触发器?

实施例:

insert into table1 column1 
select column1 from table2 where condition = 'Never met' 

输出:

(0 row(s) affected) // 0 rows inserted 
(1 row(s) affected) // log from trigger 

愿它由 '普遍的' 触发引起(声明插入,更新,删除在一次)? 我知道这更像是假设的问题,我必须接受这种行为。但为什么会发生?对我来说完全是无稽之谈。 我使用SQL Server 2005的

- kwitee

回答

7

因为他们是documented这样做呢?

DML触发器在用户试图通过数据操纵语言(DML)事件修改数据时执行。 DML事件是表或视图上的INSERT,UPDATE或DELETE语句。这些触发器在触发任何有效事件时触发,,而不管任何表行是否受到影响。

我强调

也许是毫无意义的,但也许它会花费更多的时间和开发工作的微软原来,当创建一个抑制触发一个特殊的代码路径没有影响行。

这只是另一个例子,你需要仔细设计触发器来处理inserteddeleted潜在地包含0,1行或许多行。


(另外,从一个关系来看,不含元组集可以仍然是在倍有趣)

+0

我遇到了这个问题,并及时解决之前许多(更多)的眼睛在我的答案中的一个明显的错误可以看到你的答案。 :) 谢谢! – 2013-03-13 10:34:34

+0

我的问题是关于他们为什么决定这样做。我正在寻找另一个可以节省开发时间的理由。但是我找不到任何东西,对我来说这非常不直观,使得创建触发器更复杂一些。不过谢谢。 – kwitee 2013-03-14 09:45:33

0

每当与一个表关联的事件发生时例如甲SQL触发被执行或烧制,插入,更新或删除,而不是选择语句。重新触发触发器以确保表已更新或插入或删除。

问候, sa.va3feb