SQL MS Server 2008 - Trigger zum einfügen neuer Datensätze auf Basis eines INSERTs

palaber

Captain
Registriert
Juni 2006
Beiträge
3.856
Hallo Leute,
ich hänge mal wieder :freak: - Ganz grob gesagt würde ich gerne einen Trigger verwenden um eine bestimmte Operation auszuführen sobald ich einen INSERT auf einer Tabelle ausführe. Dazu soll bei einem INSERT Befehl die Daten der Tabelle "inserted" verwendet werden und automatisch zu anderen Datensätzen der Tabelle (auf der der INSERT Befehl ausgeführt wurde) hinzugefügt werden.

Grundlage hierzu ist eine Tabelle, nennen wir sie tblPreisliste mit folgenden Spalten (mit Beispieldaten):
Preisliste | Artikel | Preis | AbDatum
A | 642 | 1,00 | 01.01.15
B | 642 | 1,50 | 01.01.15
A | 200 | 1,00 | 01.01.15
A | 199 | 1,00 | 01.01.15

Zusätzlich gibt es noch eine Tabelle tblReferenz (sehr vereinfacht dargestellt)
Artikel | ReferenzArtikel
199 | 642
200 | 642
Diese Tabelle gibt an welche Artikel durch einen INSERT eines Artikels der tblPreisliste mit versorgt werden müssen.

Sprich wird in tblPreisliste für den Artikel 642 eine neue Preisliste erstellt müssen die Artikel 199 und 200 die selben Daten erhalten:
Preisliste | Artikel | Preis | AbDatum
C | 642 | 2,00 | 01.02.15 <--- INSERT Anweisung soll diesen Datensätze erzeugen
C | 199 | 2,00 | 01.02.15 <--- automatisch durch Trigger
C | 200 | 2,00 | 01.02.15 <--- automatisch durch Trigger

Anbei mein aktueller Trigger, der sich noch nicht auswirkt:
Code:
ALTER TRIGGER TriggerTest	'Triggername'
   ON tblPreisliste		'Tabelle die für Trigger verwendet wird'
   AFTER INSERT
AS 
BEGIN

  INSERT INTO tblPreisliste (Preisliste, Artikel, Preis, DatumAb)
    SELECT  inserted.Preisliste, BGARTIKEL.ARartikelnr, inserted.Preis, inserted.DatumAb
    FROM inserted INNER JOIN tblReferenz ON tblReferenz.Artikel = inserted.PLartikelnr
    'zur verbesserten Übersicht wurde hier Artikelnr fest hinterlegt...'
   WHERE tblReferenz.ReferenzArtikel = '642' 
END

Irgendwie dachte ich kann es mit nem einfachen INSERT INTO lösen. Langsam denke ich aber, ich benötige sowas wie nen Cursor oder eine Schleife inkl. tmpTabelle. Dann könnte ich ja alle Artikel mit dem ReferenzArtikel 642 durchlaufen und in der tblPreislisten einfügen (mit INSERT INTO ... VALUES...). Hab aber irgendwie im Hinterkopf, das es mit dem obigen INSERT INTO performanter ist und es auch gehen sollte. Allerdings komm ich einfach nicht drauf wie ich vorgehen muss.

Danke für eure Hilfe!
 
Zuletzt bearbeitet:
Das erste, was mir hier auffällt ist die Rekursion in deinem Trigger.
Der Server wird das standardmäßig gar nicht zulassen, es sei denn recursive triggers ist erlaubt, und selbst dann wird er aussteigen, weil eine Rekursionstiefe > 32 nicht zugelassen wird.
 
Ein Instead Of Insert Trigger wäre noch eine Möglichkeit.
Allerdings ist ein Trigger keine gute Wahl um diese Logik zu implementieren. Schlecht zu debuggen und kann bei falscher Implementierung Performanceprobleme verursachen.

Ich würde die Referenztabelle lieber auslesen (wenn möglich cachen) und die benötigten Inserts selber durchführen.
 
Das mit dem Trigger ist ne Vorgabe / Aufgabenstellung die ich erfüllen muss.

Ich habe mich jetzt mal an den Microsoft Artikel gehalten: http://support.microsoft.com/kb/111401/de
Hintergrund ist eine temporäre Tabelle in der alle Artikelnr enthalten sind die auf die geänderte ReferenzArtnr zugreifen.
Also die 199 und 200 für ein Insert / update / delete bei ArtNr 642.
Die tmp-Tabelle wird wie in dem MS-Artikel beschrieben. Abhängig vom Vorgang wird ein DELETE / INSERT / UPDATE
durchgeführt. Grundlagen sind die "inserted" bzw. "deleted" Tabelle und die Artikelnr des aktuellen Datensatzes der tmp-Tabelle.

Codeausschnitt für INSERT:
Code:
ALTER TRIGGER TriggerTest
   ON tblPreislisten
   AFTER INSERT
AS 
BEGIN

	DECLARE @RefArtNr As int   'Artikelnr auf die Referenz liegt (642)'
	DECLARE @InsArtNr As int   'Artikelnr die geändert werden soll (199 / 200)'

	'ACHTUNG: inserted Tabelle enthält bei mir IMMER nur einen Datensatz!'	
	SET @RefArtNr = (SELECT PLartikelnr FROM inserted)  'ermittelt Artikelnr aus inserted Tabelle' 
		
	SET rowcount 0
	'Ermittelt alle Artikelnr mit Referenz auf 642 und erstellt tmp Tabelle'
	SELECT DISTINCT NULL mykey, ARartikelnr 
		INTO #tmp FROM BGARTIKEL WHERE BGARTIKEL.ARLeitArtPreis = @RefArtNr
	
	SET rowcount 1
	UPDATE #tmp SET mykey = 1
	
	WHILE @@rowcount > 0
	BEGIN
	  SET rowcount 0
          'ermittelt aktuelle ArtNr der TmpTabelle'
	  SET @InsArtNr = (SELECT ARartikelnr FROM #tmp WHERE mykey = 1)   
		
          'fügt Datensatz von 642 in den Artikelnummern 199 / 200 ein..)'
	  INSERT INTO tblPreislisten(Preisliste, Artikel, Preis, AbDatum)
	    SELECT  inserted.Preislisten, @InsArtNr, inserted.Artikel, inserted.Preis, inserted.AbDatum
	    FROM inserted
			  
	   DELETE #tmp WHERE mykey = 1
	   SET rowcount 1
	   UPDATE #tmp SET mykey = 1
	END
	SET rowcount 0

END

Ob das ganze so jetzt die "feine Art" ist weiß ich nicht. Aber anders konnte ich es mit einem TRIGGER nicht lösen. Evtl. hat ja noch jemand nen Tipp wie man es noch mit einem TRIGGER lösen könnte.
 
Zuletzt bearbeitet:
Zurück
Oben