Dieser Prozess hat mehrere Schritte, die sich in verschiedenen Tabellen einer Datenbank widerspiegeln:
Produktion - & gt; UPDATE
für die Inventory-Tabelle mit etwas wie
Das obige füttert eine Protokolltabelle mit einem TRIGGER
wie folgt:
Und schließlich sollte jedes Update INSERT
eine Zeile in eine Finanztabelle aufnehmen, die ich oben zu TRIGGER hinzugefügt habe:
Das Problem ist mit dieser Zeile:
%Vor% soll den letzten Kontostand berechnen. Da aber CROSS APPLY
alle INSERTS
als Stapel behandelt, wird die Berechnung aus dem gleichen letzten Datensatz ausgeführt, und ich erhalte einen falschen Saldo. Beispiel:
Was wäre der Weg, um das zu lösen? Ein Trigger für die Tabelle FINS
anstatt für die Saldenberechnung?
Die vorhandene Logik in Ihrer Abfrage verstehen
UPDATE
-Anweisung wird trigger
nur einmal für einen Satz oder einen Stapel auslösen, die Join-Bedingungen erfüllen. Die eingefügte Anweisung enthält alle Datensätze, die aktualisiert werden. Dies liegt an der BATCH-Verarbeitung, nicht wegen CROSS APPLY
, sondern wegen UPDATE
.
In dieser Abfrage von Ihnen
%Vor%Für jede CORP von einer Äußeren Abfrage wird die gleiche BAL zurückgegeben.
%Vor%Das heißt, Ihre innere Abfrage wird jedes Mal durch 1000 ersetzt (Wert, den Sie in Ihrem Beispiel verwendet haben) CORP = 'XYZ'
%Vor%Jetzt enthält Ihre eingefügte Anweisung alle Datensätze, die eingefügt werden. Also werden die Kosten jedes Eintrags um 1000 subtrahiert. Daher erhalten Sie ein unerwartetes Ergebnis.
Lösungsvorschlag
Nach meinem Verständnis wollen Sie eine kumulative Häufigkeit Art der Sache berechnen. Oder letzte laufende Summe
Datenvorbereitung für Problemstellung. Benutzte meine Dummy-Daten, um dir eine Idee zu geben.
%Vor%Alternative Logik zum Abziehen der Kosten vom letzten laufenden Kontostand.
%Vor%Ausgabe
%Vor%Sie müssen Ihre Spalten ein wenig twittern, um diese Funktionalität in Ihren Auslöser zu bekommen.
Ich denke, Sie können einen Trigger auf den Flossen versuchen.
Sie können IDENT_CURRENT ('Table') verwenden, um den letzten Primärschlüssel aus der Tabelle zu übernehmen und eine Auswahl zu treffen.
Ich denke, es ist besser als "Top 1 auswählen".
Um den letzten Bilanzwert zu erhalten, setzen Sie eine Variable last_bal = wählen Sie bal aus FINS, wobei primary_key = Ident_Current ("FINS")
istgut
first sql ist ein Spiel, in dem es mit Gruppen oder besser gesagt mit "set" funktioniert, also musst du immer darüber nachdenken.
Wenn Sie mit einem einfachen Gegenstand arbeiten, ist es richtig, es ist vielleicht besser, sich an
zu wenden %Vor%Ich gebe Ihnen keine genaue Abfrage. Vergessen Sie einen Moment den Auslöser. Weil Sie Ihre Abfrage nicht testen können. Ich schlage vor, Output-Klausel zu verwenden. Dies wird Ihnen helfen, die richtige Abfrage zu erstellen und zu testen. Diese Abfrage läuft in Ordnung, (wenn Sie Merge verwenden können, dann ist das am besten).
%Vor%Sie haben jetzt einen Wert in die Tabellenvariable @t
eingefügt %Vor%Überprüfen Sie diese Abfrage bis hierhin. Denken Sie an die Optimierung oder triggern Sie später. Ich denke, dass ich guten Vorschlag gab. Und ich denke Subtraktion ist kein Problem. Ich sage, alles in Ausgangsklausel zu setzen und die Frage zu analysieren und sie zu prüfen.
Sie können CTE auch innerhalb des Triggers verwenden, aber wie testen Sie es?
%Vor%Wenn Sie, ähnlich wie bei @ Shantanus Methode, eine Sequenz mit inserted verknüpfen könnten, könnte die virtuelle Tabelle, die dem Trigger zugeordnet ist, dies tun, indem Sie alle Kosten, die vor dem aktuellen Datensatz liegen, subtrahieren.
Dies könnte durch Hinzufügen einer Zeilenversion zu STOR erreicht werden, die automatisch mit jedem Löschen aktualisiert wird.
Dann statt:
((SELECT TOP 1 BAL FROM FINS WHERE COMPANY = CORP ORDER BY TS DESC)- COST)
from inserted ...
Machen Sie die Zeilenversion RV, und:
%Vor%Sollte tun, was Sie wollen. Du könntest dies mit einem Zeitstempel machen, der mehr auffindbar ist als CURRENT_TIMESTAMP, der, glaube ich, nur auf Sekunden reduziert wird, aber das erfordert, dass du ihn in der UPDATE-Anweisung aktualisierst. Die Zeilenversion kann Probleme mit Ihren STOR-INSERT-Anweisungen verursachen.
Tags und Links sql-server tsql cross-apply