Announcement

Collapse
No announcement yet.

INSERT-Trigger in SQL Server 2005 - Verweis auf neu eingefügte Zeile

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • INSERT-Trigger in SQL Server 2005 - Verweis auf neu eingefügte Zeile

    Hallo!

    Ich brauche für SQL Server 2005 eine Möglichkeit bei einem INSERT-Trigger die neu eingefügte Zeile zu referenzieren.
    Grund: In einer Tabelle T1 wird ein Eintrag gemacht, wenn eine Person einen Platz in einem Kurs erhalten hat. Wenn also eine Person einen Platz in Kurs A erhält (= INSERT), dann möchte ich die Teilnehmerzahl in der Tabelle T2 - in der die Informationen zu Kursen gespeichert sind - entsprechend um eins erhöhen.
    Dazu benötige ich aber natürlich einen Möglichkeit bei der aktuell eingefügten Zeile herauszufinden, dass die Person eben einen Platz in Kurs A erhalten hat und nicht in irgendeinem anderen Kurs.

    In Oracle funktioniert das in etwa so:
    CREATE TRIGGER <trigger_name>

    AFTER INSERT ON <table_name>

    REFERENCING NEW AS <new_row_name>

    FOR EACH ROW [WHEN (<trigger_condition>)]]

    <trigger_body>

    Weiß jemand, wie man sowas in SQL Server 2005 macht?

    Viele Grüße,
    Peejay

  • #2
    also im SQL Server 2000 (wahrscheinlich auch 2005) hat man eine Tabelle Inserted!
    Bsp-Code:
    CREATE TRIGGER trig_test
    ON T1 -- <table_name, sysname, pubs.dbo.sales>
    FOR INSERT --DELETE, INSERT, UPDATE --Anpassen
    AS
    BEGIN
    Select * from inserted

    END

    Hoffe das hilft

    Gruß
    Thomas

    Comment


    • #3
      Hallo!

      Vielen Dank Thomas! Das war genau das was ich gesucht habe!

      Der Trigger funktioniert einwandfrei und sieht jetzt so aus:

      SET ANSI_NULLS ON
      USE Anmeldesystem;
      GO
      CREATE TRIGGER incrementAnzVergeben
      ON [Anmeldesystem].[dbo].[Hat_Platz]
      AFTER INSERT
      AS
      BEGIN
      -- SET NOCOUNT ON added to prevent extra result sets from
      -- interfering with SELECT statements.
      SET NOCOUNT ON;

      DECLARE @Nummer int
      SELECT @Nummer = inserted.[Gruppe] FROM inserted

      IF @Nummer IS NOT NULL
      BEGIN
      UPDATE [Anmeldesystem].[dbo].[Gruppe]
      SET [anzVergeben] = [anzVergeben] + 1
      FROM inserted
      WHERE inserted.Anmeldeobjekt = Gruppe.Anmeldeobjekt
      AND inserted.Gruppe = Gruppe.Gruppennr;

      UPDATE [Anmeldesystem].[dbo].[Anmeldeobjekt]
      SET [anzVergeben] = [anzVergeben] + 1
      FROM inserted
      WHERE inserted.Anmeldeobjekt = Anmeldeobjekt.Id;
      END

      IF @Nummer IS NULL
      BEGIN
      UPDATE [Anmeldesystem].[dbo].[Anmeldeobjekt]
      SET [anzVergeben] = [anzVergeben] + 1
      FROM inserted
      WHERE inserted.Anmeldeobjekt = Anmeldeobjekt.Id;
      END

      UPDATE [Anmeldesystem].[dbo].[Priorisierung]
      SET [anzVergeben] = [anzVergeben] + 1
      FROM inserted
      WHERE inserted.Anmeldeobjekt = Priorisierung.Anmeldeobjekt
      AND inserted.Priorisierung = Priorisierung.DurchlaufNr;

      UPDATE [Anmeldesystem].[dbo].[Anmeldung]
      SET [Hat_Platz] = 'True'
      FROM inserted
      WHERE inserted.StudIPKennung = Anmeldung.StudIPKennung
      AND inserted.Anmeldeobjekt = Anmeldung.Anmeldeobjekt;
      END
      GO

      Viele Grüße,
      Peejay

      Comment


      • #4
        Der Vollständigkeit halber hier auch noch der Delete-Trigger (gültig für ein DELETE, das beliebig viele Zeilen betrifft):

        SET ANSI_NULLS ON
        GO
        SET QUOTED_IDENTIFIER ON
        GO
        USE Anmeldesystem;
        GO
        CREATE TRIGGER decrementAnzVergeben
        ON [Anmeldesystem].[dbo].[Hat_Platz]
        AFTER DELETE
        AS
        BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;

        UPDATE [Anmeldesystem].[dbo].[Gruppe]
        SET [anzVergeben] = [anzVergeben] -
        (SELECT Count(*)
        FROM deleted
        WHERE deleted.Anmeldeobjekt = Gruppe.Anmeldeobjekt
        AND deleted.Gruppe IS NOT NULL
        AND deleted.Gruppe = Gruppe.Gruppennr)

        UPDATE [Anmeldesystem].[dbo].[Anmeldeobjekt]
        SET [anzVergeben] = [anzVergeben] -
        (SELECT Count(*)
        FROM deleted
        WHERE deleted.Anmeldeobjekt = Anmeldeobjekt.Id)

        UPDATE [Anmeldesystem].[dbo].[Priorisierung]
        SET [anzVergeben] = [anzVergeben] -
        (SELECT Count(*)
        FROM deleted
        WHERE deleted.Anmeldeobjekt = Priorisierung.Anmeldeobjekt
        AND deleted.Priorisierung = Priorisierung.DurchlaufNr)

        UPDATE [Anmeldesystem].[dbo].[Anmeldung]
        SET [ZK_min_einmal_erfuellt] = 'False', [Hat_Platz] = 'False'
        FROM deleted
        WHERE deleted.StudIPKennung = Anmeldung.StudIPKennung
        AND deleted.Anmeldeobjekt = Anmeldung.Anmeldeobjekt

        END
        GO

        Comment


        • #5
          Hi, sieht doch gut aus... nur eins noch:
          Im Insert-Trigger die Zuweisung
          SELECT @Nummer = inserted.[Gruppe] FROM inserted
          ist mit Vorsicht zu geniessen... wenn in der Inserted-Tabelle mehr als ein Datensatz steht, knallt´s. Immer besser für eine "ganze" Tabelle schreiben, oder Top 1 benutzen, also so: SELECT top 1 @Nummer = inserted.[Gruppe] FROM inserted.

          Gruß
          Thomas

          Comment


          • #6
            Hallo,

            ...ist mit Vorsicht zu geniessen... wenn in der Inserted-Tabelle mehr als ein Datensatz steht, knallt´s.
            der Hinweis von Thomas ist sehr wichtig. Ein Trigger wird unabhängig von der Anzahl der von der auslösenden Aktion betroffenen Datensätze am Ende nur ein einziges Mal ausgelöst. Somit muss ein Trigger mit 3 Fällen rechnen:

            1. Es sind keine Datensätze betroffen
            2. Es ist genau 1 Datensatz betroffen
            3. Es sind mehrere Datensätze betroffen

            Wenn in allen Fällen eine datensatzbezogene Reaktion notwendig ist, kann im Multi-Row-Fall ein Cursor einen Per-Row-Trigger simulieren. Die Oracle-Option FOR EACH ROW kann beim MS SQL Server durch die Kombination eines INSTEAD OF-Trigger mit einem CURSOR implementiert werden. Das folgende Beispiel demonstriert das Prinzp:

            <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border-top: windowtext 1pt solid; padding-top: 0pt; border-left: windowtext 1pt solid; padding-left: 0pt; border-right: windowtext 1pt solid; padding-right: 0pt; border-bottom: windowtext 1pt solid; padding-bottom: 0pt;"><p style="margin: 0px;"><span style="color: blue;">SET NOCOUNT ON</span>;</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;"><span style="color: blue;">USE </span>tempdb;</p><p style="margin: 0px;">GO</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;"><span style="color: blue;">IF OBJECT_ID</span>(<span style="color: #a31515;">'dbo.TestTbl'</span>) <span style="color: blue;">IS NOT NULL</span></p><p style="margin: 0px;">&nbsp; <span style="color: blue;">DROP TABLE </span>dbo.TestTbl;</p><p style="margin: 0px;">GO</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;"><span style="color: blue;">CREATE TABLE </span>dbo.TestTbl</p><p style="margin: 0px;">(</p><p style="margin: 0px;">&nbsp; keycol&nbsp; <span style="color: blue;">INT </span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">NOT NULL PRIMARY KEY</span>,</p><p style="margin: 0px;">&nbsp; datacol <span style="color: blue;">VARCHAR</span>(10) <span style="color: blue;">NOT NULL</span></p><p style="margin: 0px;">)</p><p style="margin: 0px;">GO</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;"><span style="color: blue;">CREATE TRIGGER </span>trTestTblPerRow </p><p style="margin: 0px;">&nbsp; <span style="color: blue;">ON </span>dbo.TestTbl </p><p style="margin: 0px;">&nbsp; INSTEAD <span style="color: blue;">OF INSERT</span></p><p style="margin: 0px;"><span style="color: blue;">AS</span></p><p style="margin: 0px;">&nbsp; <span style="color: blue;">DECLARE </span>@rc <span style="color: blue;">AS INT</span>;</p><p style="margin: 0px;">&nbsp; <span style="color: blue;">SET </span>@rc = @@ROWCOUNT;</p><p style="margin: 0px;">&nbsp; <span style="color: blue;">IF </span>@rc = 0 </p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">RETURN</span>;</p><p style="margin: 0px;">&nbsp; <span style="color: blue;">IF </span>@rc = 1</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">BEGIN</span></p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: green;">-- Trigger ist nur f&#252;r 1 Datensatz zust&#228;ndig</span></p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">INSERT INTO </span>dbo.TestTbl <span style="color: blue;">SELECT </span>* <span style="color: blue;">FROM </span>inserted;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">END</span></p><p style="margin: 0px;">&nbsp; <span style="color: blue;">ELSE</span></p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">BEGIN</span></p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: green;">-- Trigger ist f&#252;r mehrere Datens&#228;tze zust&#228;ndig</span></p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">DECLARE </span>@keycol <span style="color: blue;">AS INT</span>, @datacol <span style="color: blue;">AS VARCHAR</span>(10);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">DECLARE </span>c <span style="color: blue;">CURSOR </span>FAST_FORWARD <span style="color: blue;">FOR</span></p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">SELECT </span>keycol, datacol <span style="color: blue;">FROM </span>inserted;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">OPEN </span>c;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">FETCH NEXT FROM </span>c <span style="color: blue;">INTO </span>@keycol, @datacol;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">WHILE </span>@@fetch_status = 0</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">BEGIN</span></p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">INSERT INTO </span>dbo.TestTbl(keycol, datacol)</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">VALUES</span>(@keycol, @datacol);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">FETCH NEXT FROM </span>c <span style="color: blue;">INTO </span>@keycol, @datacol;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">END</span></p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">CLOSE </span>c;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: blue;">DEALLOCATE </span>c;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">END</span></p><p style="margin: 0px;">GO</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;"><span style="color: green;">-- 0 Rows</span></p><p style="margin: 0px;"><span style="color: blue;">INSERT INTO </span>dbo.TestTbl <span style="color: blue;">SELECT </span>1, <span style="color: #a31515;">'A' </span><span style="color: blue;">WHERE </span>1 = 0;</p><p style="margin: 0px;">GO</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;"><span style="color: green;">-- 1 Row</span></p><p style="margin: 0px;"><span style="color: blue;">INSERT INTO </span>dbo.TestTbl <span style="color: blue;">SELECT </span>1, <span style="color: #a31515;">'A'</span>;</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;"><span style="color: green;">-- Multi Rows</span></p><p style="margin: 0px;"><span style="color: blue;">INSERT INTO </span>dbo.TestTbl</p><p style="margin: 0px;">&nbsp; <span style="color: blue;">SELECT </span>2, <span style="color: #a31515;">'B'</span></p><p style="margin: 0px;">&nbsp; <span style="color: blue;">UNION ALL</span></p><p style="margin: 0px;">&nbsp; <span style="color: blue;">SELECT </span>3, <span style="color: #a31515;">'C'</span></p><p style="margin: 0px;">&nbsp; <span style="color: blue;">UNION ALL</span></p><p style="margin: 0px;">&nbsp; <span style="color: blue;">SELECT </span>4, <span style="color: #a31515;">'D'</span>;</p><p style="margin: 0px;">GO</p><p style="margin: 0px;">&nbsp;</p><p style="margin: 0px;"><span style="color: green;">-- Ergebnis pr&#252;fen</span></p><p style="margin: 0px;"><span style="color: blue;">SELECT </span>* <span style="color: blue;">FROM </span>dbo.TestTbl</p></div>
            Zuletzt editiert von Andreas Kosch; 31.01.2007, 08:33.

            Comment

            Working...
            X