如果没有更新记录,任何理由触发AFTER UPDATE触发器?

时间:2015-12-24 14:05:19

标签: sql-server tsql triggers

考虑这个SQL脚本:

- NSManagedObjectContext NSManagedObjectContext rollback
- NSManagedObjectContext NSManagedObjectContext discardEditing
- NSManagedObjectContext NSManagedObjectContext isEditing
- NSManagedObjectContext NSManagedObjectContext propagatesDeletesAtEndOfEvent
- NSManagedObjectContext NSManagedObjectContext setPropagatesDeletesAtEndOfEvent:
- NSManagedObjectContext NSManagedObjectContext performBlockAndWait:
- NSManagedObjectContext NSManagedObjectContext processPendingChanges
- NSManagedObjectContext NSManagedObjectContext _processRecentChanges:
- NSManagedObjectContext NSManagedObjectContext _postRefreshedObjectsNotificationAndClearList
- NSManagedObjectContext NSManagedObjectContext _processReferenceQueue:
- NSManagedObjectContext NSManagedObjectContext deleteObject:
- NSManagedObjectContext NSManagedObjectContext _registerClearStateWithUndoManager
- NSManagedObjectContext NSManagedObjectContext _establishEventSnapshotsForObject:
- NSManagedObjectContext NSManagedObjectContext _enqueueEndOfEventNotification
- NSManagedObjectContext NSManagedObjectContext _postObjectsDidChangeNotificationWithUserInfo:
- NSManagedObjectContext NSManagedObjectContext processPendingChanges
- NSManagedObjectContext NSManagedObjectContext _processRecentChanges:
- NSManagedObjectContext NSManagedObjectContext _registerClearStateWithUndoManager
- NSManagedObjectContext NSManagedObjectContext _updateUnprocessedOwnDestinations:
- NSManagedObjectContext NSManagedObjectContext _propagatePendingDeletesAtEndOfEvent:
- NSManagedObjectContext NSManagedObjectContext _processPendingDeletions:withInsertions:withUpdates:withNewlyForgottenList:withRemovedChangedObjects:
- NSManagedObjectContext NSManagedObjectContext _processPendingInsertions:withDeletions:withUpdates:
- NSManagedObjectContext NSManagedObjectContext _processPendingUpdates:
- NSManagedObjectContext NSManagedObjectContext _registerUndoForModifiedObjects:
- NSManagedObjectContext NSManagedObjectContext _registerUndoForInsertedObjects:
- NSManagedObjectContext NSManagedObjectContext _registerUndoForDeletedObjects:withDeletedChanges:
- NSManagedObjectContext NSManagedObjectContext _registerUndoForOperation:withObjects:withExtraArguments:
- NSManagedObjectContext NSManagedObjectContext _updateUndoTransactionForThisEvent:withDeletions:withUpdates:
- NSManagedObjectContext NSManagedObjectContext _clearRefreshedObjects
- NSManagedObjectContext NSManagedObjectContext _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:
- NSManagedObjectContext NSManagedObjectContext _postObjectsDidChangeNotificationWithUserInfo:
- NSManagedObjectContext NSManagedObjectContext _processRecentlyForgottenObjects:
- NSManagedObjectContext NSManagedObjectContext _forgetObject:propagateToObjectStore:
- NSManagedObjectContext NSManagedObjectContext _forgetObject:propagateToObjectStore:removeFromRegistry:
- NSManagedObjectContext NSManagedObjectContext _processReferenceQueue:
- NSManagedObjectContext NSManagedObjectContext _isDeallocating
- NSManagedObjectContext NSManagedObjectContext _forgetObject:propagateToObjectStore:
- NSManagedObjectContext NSManagedObjectContext _forgetObject:propagateToObjectStore:removeFromRegistry:
- NSManagedObjectContext NSManagedObjectContext _resetAllChanges
- NSManagedObjectContext NSManagedObjectContext _clearUnprocessedUpdates
- NSManagedObjectContext NSManagedObjectContext _clearUpdates
- NSManagedObjectContext NSManagedObjectContext _clearUnprocessedInsertions
- NSManagedObjectContext NSManagedObjectContext _clearInsertions
- NSManagedObjectContext NSManagedObjectContext _clearUnprocessedDeletions
- NSManagedObjectContext NSManagedObjectContext _clearDeletions
- NSManagedObjectContext NSManagedObjectContext _clearLockedObjects
- NSManagedObjectContext NSManagedObjectContext _clearRefreshedObjects
- NSManagedObjectContext NSManagedObjectContext _incrementUndoTransactionID
- NSManagedObjectContext NSObject willChangeValueForKey:
- NSManagedObjectContext NSObject observationInfo
- NSManagedObjectContext NSObject _implicitObservationInfo
- NSManagedObjectContext NSObject didChangeValueForKey:
- NSManagedObjectContext NSObject _pendingChangeNotificationsArrayForKey:create:
- NSManagedObjectContext NSManagedObjectContext setPropagatesDeletesAtEndOfEvent:
- NSManagedObjectContext NSManagedObjectContext performBlockAndWait:

从Management Studio或类似应用程序运行它,您将获得如下输出:

enter image description here

当服务器执行BEGIN TRAN CREATE TABLE foo ( Id INT NOT NULL PRIMARY KEY, Name NVARCHAR(20) NULL ); GO CREATE TRIGGER [foo_insert] ON foo AFTER UPDATE AS BEGIN SET NOCOUNT ON; SELECT COUNT(*) from inserted; END GO INSERT INTO foo VALUES(1, 'Jonh'); INSERT INTO foo VALUES(2, 'Mary'); INSERT INTO foo VALUES(3, 'Peter'); INSERT INTO foo VALUES(4, 'Helen'); SELECT * FROM foo; CREATE TABLE #bar ( Id INT NOT NULL ); UPDATE foo SET foo.Name = NULL FROM #bar JOIN foo ON #bar.Id = foo.Id; SELECT * FROM foo; DROP TABLE foo; ROLLBACK TRAN 语句时,此处AFTER UPDATE触发器触发。由于UPDATE ... FROM为空,因此无需更新,但触发仍然会触发(“结果”窗格中的第二个结果)。

SQL Server是否有任何理由这样做? 换句话说,我的意思是,#bar触发器必须在更新后 - 也就是说,在某些记录更新后?否?

3 个答案:

答案 0 :(得分:4)

这是记录在案的行为。它为什么这样工作?你不得不问那个决定这样写的人。我的猜测是表现。如果触发器不必检查触发它们的操作以查看它是否执行任何操作,则触发器可能更快。

你做了更新,解雇了UPDATE TRIGGER。那很快。

你做了一个更新,让我检查是否有任何行被更改。没有?根本不开火。那个慢了。

即使没有更新行,想要拥有UPDATE TRIGGER的可怜程序员也会执行某项操作会发生什么?那他/她呢,嗯?

答案 1 :(得分:1)

评论太长了。

显然,如果没有更新行,则没有关键的原因来执行触发器。这是大多数数据库的行为。

另一方面,这样做几乎没有什么害处。 SQL Server使用inserteddeleted视图来提供已修改的行列表。如你所见,这些可能是空的。大多数触发器使用inserteddeleted的内容,并且当这些内容为空时不执行任何操作。

我可以想象这会有用的情况,特别是出于安全和审计目的。这允许update触发器跟踪所有更新和尝试更新。这是许多其他数据库无法做到的事情。

答案 2 :(得分:0)

您的更新未更新任何记录。

UPDATE
    foo
SET
    foo.Name = NULL
FROM
    #bar JOIN foo ON #bar.Id = foo.Id;

您将获得0,并且当您在当前交易中没有任何插入时,您还要求返回插入的所有记录。

如果您想进行计数,您将需要一个带循环的事务和某种计数器,或者更改此SELECT COUNT(*) from inserted;来计算特定事件。