Quantcast
Channel: Für Entwickler: SQL Server Forum
Viewing all articles
Browse latest Browse all 1772

Triggerproblematik, Verständnisfrage, Vergleich Oracle/Firebird nun zu MSSQL

$
0
0

Hallo liebe Gemeinde,

gerade ereilt mich ein neues Problem, eine Aufgabe. Und zwar ist im Firebird folgendes realisiert:

.. es wird in einer Tabelle überprüft, ob noch ein Datensatz vorhanden ist, in welchem ein Bild den Status 1 hat, wenn nein, dann werden alle Datensätze von dem Produkt (alle Bilder) mit Status 6 versehen. Dabei hilft die Funktion:

select 1 from rdb$database where exists(select count(*) from tpictures where Produkt = :new.produkt and status = 1) into :i_exists;

if(i_exists = 1) then update tpictures set status = 6 where Produkt = :new.produkt.

 

die Bilder werden also zum Löschen freigegeben, vorher hatten sie entweder Status 1 oder Status 5

 

Das funktionierte sehr gut und war performanter, als wenn ich das in die Funktion zum Eintragen der Daten implementiert hätte.

 

Nun haben wir MSSQL. Ich setzte das wie folgt um: (kd_id und li_id betrifft das "Produkt"

 

ALTER TRIGGER [dbo].[t_pictures_au0]

ON [dbo].[T_PICTURES]

AFTER UPDATE

AS

BEGIN

SET NOCOUNT ON;

declare @kd_id datetime;

declare @li_id integer;

declare @status smallint;

select @kd_id = kd_id, @li_id = li_id, @status = status from inserted;

 

if @status = 5

begin

if (not exists (select 1 from t_pictures where status < 5 and kd_id = @kd_id

and li_id = @li_id))

update t_pictures set status = 6 where kd_id = @kd_id and li_id = @li_id;

end

END;

 

Die Reaktion eines (wisssenden MSSQL) Kunden war dann folgende:

Die Trigger wären(fast) ausnahmslos darauf ausgelegt, dass über Insert/Update/Delete immer nur ein einziger Datensatz bearbeitet wird.

Und das wäre eine der gefährlichsten Varianten, Trigger zu programmieren. Es wurde das Beispiel genannt:

UPDATE dbo.T_PICTURES SET Status = 5 WHERE LI_ID = 6 AND STATUS = 1 Damit werden in der Datenbank 1627 Datensätze aktualisiert.

Der Trigger [dbo].[t_pictures_au0] findet jedoch nur die Datensätze und auf Status 6 setzen, die eben das Prudukt in sich tragen, da sich dies aus den "letzten" Werten für Produkt-ID ergibt.

Ich hätte die (falsche) Annahme, dass eine Anweisung immer nur einen Ergebnis-Datensatz betrifft und somit die Zuweisung von Werten der Tabelle [inserted] auf diskrete Variablen zulässig wäre. Ich sollte die Trigger neu schreiben um mehrere Zeilen in den Tabellen konsistent zu verarbeiten und mich mit outer apply beschäftigen, ja ich sollte Trigger eigentlich vermeiden, statt dessen eine Relation verwenden.

 

Kann mir bitte j​emand erklären warum diese Variante des Triggers gefährlich ist, wie sich die Konzepte der Trigger unterscheiden? Ich programmiere seit fast 13 Jahren Firebird, da diese Variante im MSSQL gut funktioniert war ich eigentlich der Meinung, dass diese Vorgehensweise richtig ist. Bitte klärt mich auf, Danke :D


Viewing all articles
Browse latest Browse all 1772


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>