Announcement

Collapse
No announcement yet.

Felder bei Insert/Update-Trigger anpassen

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

  • Felder bei Insert/Update-Trigger anpassen

    Hallo Zusammen,
    Ich bin MSSQL-Neuling und beschäftige mich hauptsächlich mit ORACLE-DB und hier ist es kein Problem während eines INSERT oder UPDATE-Triggers noch Feldinhalte im aktuellen Datensatz anzupassen. Dafür können einfach die Felder, die den neuen Datensatzinhalt repräsentieren gesetzt werden, z.B.:
    if :OLD.FELDNAME1 = ALTERWERT then
    :NEW.FELDNAME2 = NEUER WERT;
    end if;

    (Die Parameter :NEW bzw. :OLD sind in ORACLE das Gegenstück zu MSSQL "select xy from inserted" bzw. "select xy from deleted".)

    Wie geht das in MSSQL (2008) am einfachsten ?
    D.H. wie bekomme ich es hin, in Felder des getriggerten Datensatz noch Daten zu verändern ?
    Ich kann ja schlecht innerhalb des Triggers nochmal ein UPDATE-Statement auf den gleichen Datensatz absetzen, dadurch würde sich der Trigger doch selbst wieder aufrufen, oder ?

    Ich hoffe, daß ich mich einigermaßen verständlich ausgedrückt habe und bin für jede Hilfe dankbar

  • #2
    Trigger verhalten sich im SQL-Server ziemlich anders als bei Oracle.
    So gibt es beim SQL-Server zunächst mal grundlegend KEINE Row-Trigger, sondern nur Transaktionstrigger. Das heisst, der Trigger wird zB. bei einem Update-Statement, dass mit einem Schlag hunderte Datensätze ändert, nur einmal aufgerufen - nämlich am Schluß. Und dann stehen in "deleted" die Records mit ihren alten Werten und in "inserted" dieselben Records mit den neuen Werten. Ein zeilenweises Exekutieren wie in Oracle kann nicht ausgeführt werden!
    Damit sind wir schon beim nächsten Punkt: es gibt nur After-Trigger, aber keine Before-Trigger. Stattdessen kennt der SQL-Server InsteadOf-Trigger, die das Statement praktisch abfangen und man man kann dann im Trigger selber die entsprechenden Aktionen vornehmen, wobei hier dann zB. das tatsächliche Update in einem InsteadOfUpdate-Trigger diesen nicht nochmal aufruft und daher auch keine Endlosschleife produziert. Insoferne wäre in deinem Fall ein InsteadOf-Trigger erforderlich, der dann das Insert/Update mit den entsprechende ergänzten/geänderten Werten ausführt. Damit erzielt man in etwa dieselbe Funktionalität wie ein Before-Trigger.
    Der Vorteil eine InsteadOf-Triggers liegt vor allen darin, dass mam ihn auch für eine View verwenden kann, die so komplex generiert ist, dass ein normales Insert/Update/Delete mit der View eigentlich sonst gar nicht möglich wäre.
    Aber auch hier gilt: Trigger arbeiten im SQL-Server immer transaktionsbezogen, nie satzweise! Und die Tabellen "deleted" und "inserted" sind natürlich deswegen auch nur lesbar und nicht änderbar, hätte ja keinen Sinn mehr, diese temporären Werte nachträglich noch zu ändern, da es nicht auf die Originaldaten durchschlägt.

    bye,
    Helmut

    [edit]: was man noch wissen sollte:
    Kaskadierende Trigger
    Trigger-Reihenfolge
    Zuletzt editiert von hwoess; 19.08.2010, 14:46.

    Comment


    • #3
      Hallo Helmut,
      Vielen Dank für die ausführliche und schnelle Antwort !!!
      Ich werde es versuchen...
      DANKE!

      Eine andere Frage noch: Gibt es ein Pendant zu If INSERTING, DELETING, UPDATING then aus ORACLE ?
      Soweit ich gesehen habe, gibt es in MSSQL sowas nur auf Feldebene, z.B if UPDATE (NAME) then
      Ich möchte aber generell wissen, ob gerade ein UPDATE oder INSERT oder DELETE durchgeführt wird

      Grüße
      Gottfried

      Comment


      • #4
        Mir ist nichts bekannt, dass das getestet werden kann (was aber nicht heissen soll, dass es das nicht gibt). Allerdings stellt sich mir die Frage, warum man das überhaupt braucht?

        bye,
        Helmut

        Comment


        • #5
          Hallo,

          ich kenne das auch so, dass man für INSERT, UPDATE und DELETE in der Regel je einen separaten Trigger schreibt.

          Grüße
          Tino

          P.S.
          Das mit den INSTEAD OF Triggern muss ich mir auch mal genauer anschauen...
          Ich habs gleich!
          ... sagte der Programmierer.

          Comment


          • #6
            Ich möchte aber generell wissen, ob gerade ein UPDATE oder INSERT oder DELETE durchgeführt wird
            ... habe die Frage erst jetzt verstanden
            Was gemacht wird, erkennt man daran, dass bei einem Insert die deleted-Tabelle leer ist, bei einem Delete bleibt die inserted-Tabelle leer, bei einem Update sind beide gefüllt.

            Somit kann man zb sagen:

            if (select count(*) from inserted) = 0 begin
            -- es ist eine DELETE :-)
            ...

            bye,
            Helmut

            Comment


            • #7
              Hi,
              Guter Tipp ! Danke..............

              Jetzt habe ich noch eine letzte Frage zu Triggern:
              Gibt es in MSSQL analog zu ORACLE einen LOGON-Trigger, der nicht auf eine Tabellenzugriff reagiert, sondern direkt nach der DB-Anmeldung greift ?
              In ORACLE heißt das bzw. so: after logon on DB.SCHEMA

              Vielen Dank für die tatkräftige Unterstützung....

              Grüße
              G.Müller

              Comment


              • #8
                Haben wir ab SQL 2005/sp2 : Logon Trigger
                Bzw. hier nochmal von Microsoft: Logon-Trigger (MS)

                bye,
                Helmut

                Comment

                Working...
                X