2009-03-18 6 views
2

Ich habe eine Tabelle MyTable mit einem Trigger wie folgt definiert:Trigger-Ereignis wird nur einmal für Microsoft SQL Server 2005 DB ausgelöst, wenn mehr als eine Zeile aktualisiert?

ALTER TRIGGER [MyTableInsertDeleteUpdate] 
    ON [dbo].[MyTable] 
AFTER INSERT,DELETE,UPDATE 
AS 
DECLARE @id int; 
BEGIN 
    SELECT @id = ins.id FROM inserted ins; 
    IF (@id IS NOT NULL) 
    BEGIN 
     -- insert a new record to audit table 
     PRINT 'inserted/updated id: ' + CAST(@id AS VARCHAR); 
    END 
END 

Ich weiß, dass, wenn mehrere Zeilen wie diese aktualisiert werden,

UPDATE MyTable SET name = 'test rows' WHERE id in (1, 2, 3); 

die tigger nur einmal aufgerufen wird und nur die firstone in [eingefügt] wird aktualisiert. Tatsächlich kann [eingefügt] mehr als eine Zeile haben (3 in diesem Fall, wenn id 1, 2,3 existieren). In Reihenfolge Worten wird der Trigger nicht für jede Zeile ausgelöst. Ist das richtig?

Ich bin mit Microsoft SQL Server 2005

Antwort

6

Ja der Trigger ausgelöst wird einmal pro Anweisung (nicht einmal pro Zeile), dass die Änderungen macht Sie sind Indizierung. Es wird sogar ausgelöst, wenn keine Zeilen betroffen sind.

http://msdn.microsoft.com/en-us/library/ms189799(SQL.90).aspx

+0

Oh ja - wollte nur hinzufügen, sollte es kein Problem sein - Sie ändern nur Ihren Auslöser, um auf alle Zeilen in 'eingefügt' entweder mit einem Cursor oder clever sql :) –

+0

, wenn keine Zeilen betroffen sind, eingefügt Die virtuelle Tabelle muss für den Aktualisierungsfall leer sein. Ist es richtig? –

+0

Sie haben eine Zeile im 'insert' für jede eingefügte oder aktualisierte Zeile (Anweisung einfügen und aktualisieren). Überprüfen Sie diesen Link: http://msdn.microsoft.com/en-us/library/ms191300(SQL.90).aspx –

2

Wie Hojou sagte, wird Ihr Auslöser einmal pro Anweisung Feuer anstatt einmal pro betroffen Reihe. Dies ist anders als bei Datenbanken wie Interbase und Firebird und hat mich bei der ersten Verwendung von SQL Server geworfen.

Der ganze Punkt der eingefügten und gelöschten "virtuellen" Tabellen liegt darin, dass die Ereignisse auf Datensatz-SET basieren, nicht auf Zeilen basieren.

Es gibt eine beliebige Anzahl von Tutorials, die das Schreiben von SQL abdecken, um die eingefügten/gelöschten Tabellen zu verarbeiten, aber passen Sie auf die Shovelware auf. Ich habe mehr als ein paar so genannte Tutorials gesehen, die gerade von einer anderen Datenbankplattform kopiert/eingefügt wurden und nicht wirklich in SQL Server funktionieren, wie sie behaupten (einer der Top-Treffer für 'SQL Server trigger example') in Google bekommt es völlig falsch für UPDATE-Anweisungen).

This ist eine sinnvolle Einführung in Trigger und die Konzepte, die erforderlich sind, um die eingefügten und gelöschten Tabellen sinnvoll zu erklären, mit einer Erklärung, warum Ereignisse in Ihrem eigenen Beispiel fehlen. Die Microsoft-Dokumente selbst sind einigermaßen nützlich, sobald Sie ihre dumpfe, leblose Struktur und ihren Schreibstil überwunden haben.

+1

nie einen Cursor in einen Trigger setzen! Möchten Sie den Tisch stundenlang sperren, während ein Einsteckvorgang von 50000 passiert? – HLGEM

+0

Aah, guter Punkt. Ich werde meine Antwort ändern. Vielen Dank! – robsoft

0

Um von einem Einsatz Einträge in einer Audit-Tabelle einfügen Sie so etwas wie dies in der Trigger tun würde:

insert auditable (field1, field2, insert_date, insertedBy) 
select field1, field2, getdate(), user_Name() from inserted 

Kein herum täuschen mit Variablen nur einen einfachen Einsatz, basierend auf einer ausgewählten statment Einstellung.

Persönlich hätte ich einen separaten Auslöser für Einfügungen, Updates und löscht, wie Sie unterschiedliche Code für jeden wollen.

+0

Seien Sie vorsichtig bei Update-Anweisungen, da sie Duplikate in "auditable" erstellen könnten. –

+0

Sind Sie sicher, dass das funktioniert? konnte es nicht funktionieren lassen. löst nur noch für eine Zeile aus. –

Verwandte Themen