SQL-Server-trigger - SET-variable = Spalte.Wert
Ich versuche, einen trigger erstellen, die auf Tabelle component
und Protokollierung UPDATE
, DELETE
und INSERT
Bedienung an den Tisch component_history
CREATE TRIGGER component_hist
ON component
AFTER INSERT, UPDATE, DELETE
AS
DECLARE
@tr_action varchar(8),
@tr_id_compoment int,
@tr_name varchar(max),
@tr_value int
IF COLUMNS_UPDATED() <> 0 -- delete or update?
BEGIN
SET @tr_action = 'UPDATE'
ELSE -- delete
BEGIN
SET @tr_action = 'DELETE'
END
INSERT INTO component_history VALUES (@tr_id_component, @tr_name, @tr_value, @tr_action);
Wie kann ich Informationen aus Spalten (id, name, value
) aus der Tabelle component
in component_history
?
Ich versucht habe:
SET
@tr_id_component = component.id,
@tr_name = component.name,
@tr_value = component.value
aber es berichten:
Msg 4104, Ebene 16, Status 1, Prozedur component_hist, Zeile 22
Der mehrteilige Bezeichner " - Komponente.id" konnte nicht gebunden werden.
- Einige element der anwser zu deiner Frage hier: stackoverflow.com/questions/1751715/...
- Vorausgesetzt, mindestens ein insert wurde bereits erfolgreich verarbeitet (also Zeilen in der Tabelle vorhanden sind),
EXISTS (SELECT * FROM component)
wird immer wahr sein. Und Trigger einmal pro Anweisung, nicht einmal pro Zeile, so zu denken, setzen von Werten in Variablen ist immer falsch im Kopf. - Es ist eine zweite Sache, es war eine Konstruktion für ORACLE, aber MSSQL nicht unterstützt, BEVOR die Anweisung, so dass ich mit NACH nur für jetzt (ich weiß nicht, wie zu lösen, BEVOR) :((
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollte sowas ausreichen:
Einen kleine Optimierung (wenn man viel großen updates) wäre, nach der
EXISTS (select * from deleted)
Bewertung aus derSELECT
(da es derzeit beurteilt werden einmal pro Zeile).Beachten Sie auch, dass in der
UPDATE
Fall, wir sind nur die Speicherung der neuen Werte, nicht die alten Werte.Den
eingefügt
undgelöscht
pseudo-Tabellen sind etwas besonderes - Sie enthalten die Zeilen, die betroffen waren durch die Anweisung, die den Auslöser, um Feuer. Dieinserted
Tabelle enthält alle neuen Zeilen, und diedeleted
Tabelle enthält alle alten Zeilen. Dies führt zu der Logik, dass bei einerinsert
,deleted
wird leer sein (keine alten Zeilen betroffen waren durch das einfügen). Und während eindelete
,inserted
leer (keine neuen Zeilen angelegt wurden). Während einerupdate
beide Tabellen gefüllt sind.Dies ist der Grund, warum der Obere Teil der
select
gilt sowohl fürinsert
undupdate
Operationen, da sind wir mit deninserted
Tabelle. Aber wir überprüfen, ob es irgendwelche Zeilen indeleted
, um zwischen den beiden Operationen. In der unterenselect
(unterhalb derunion all
), wir die Abfrage derdeleted
Tabelle - aber wir nutzen diewhere
- Klausel, um zu verhindern, dass alle Zeilen zurückgegeben werden, wenn dies tatsächlich eineupdate
Betrieb.inserted
unddeleted
. Wenn nicht, können Sie sagen, welche bit(s) nicht klar?