Announcement

Collapse
No announcement yet.

Trigger : Problem beim UPDATE im selben Datensatz

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

  • Trigger : Problem beim UPDATE im selben Datensatz

    Hallo,

    Ich brauch einen Trigger, der beim Update im selben Datensatz noch Felder anpasst.
    Leider scheint das für die Datenbank unmöglich zu sein, weil sie so "zwei" Datensätze ändert.

    Die Fehlermeldung beim Ändern von 'datum':
    Code:
    Es wurde keine Zeile aktualisiert.
    
    Die Daten in Zeile 1 wurden nicht verarbeitet.
    Fehlerquelle: Microsoft.VisualStudio.DataTools
    Fehlernachricht: Die aktualisierten oder gelöschten Zeilenwerte machen die Zeile nicht eindeutig oder ändern mehrere Zeilen (2 Zeilen).
    Mein Trigger, der sich ohne Probleme abspeichern lässt:
    Code:
    USE [testDB]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER TRIGGER [dbo].[T_tbl_A] 
       ON  [dbo].[tbl_A]
       AFTER UPDATE 
    AS 
    
    DECLARE @ID int;
    SET @ID = (SELECT id FROM inserted);
    
    IF UPDATE (datum)
    	BEGIN 
       		UPDATE tbl_A SET update = 'TRUE' WHERE id = @ID
    	END
    Wie kann ich mit einem Trigger beim UPDATE ein zweites UPDATE hinterherschieben?

    Danke
    Frank

  • #2
    Dein Trigger ist gefährlich programmiert. Er funktioniert nämlich nur, wenn man wirklich nur einen einzigen Record updated. Ansonsten gibt es diesen Fehler. Der SQL-Server hat ja keinen Rowlevel-Trigger, der je Record aufgerufen wird, sondern einen Transactions-trigger, der einmal am Ende für alle records aufgerufen wird. Die betroffenen records finden sich in den Tabellen "inserted" bzw. "deleted".
    Wenn die ID's nun angenommen durchgehend wären und man macht ein "update tabelle set datum = getdate() where id > 10 and id < 20", dann wären da mit einem Schlag 9 Records betroffen (die man alle in "inserted" findet), das select kann aber nur eine einzige ID in die Variable @id stellen - damit gibt es eine Fehlermeldung.
    Probiere doch mal ein Update über das ManagementStudio, wo sicher nur genau ein einziger Record betroffen ist und ein Update, bei dem mehrere Records betroffen sind....
    Als Lösung müsste man entweder im Trigger mit einem Cursor arbeiten und die gesamte "inserted" Record für Record durchgehen oder im trigger prüfen, dass nur genau ein record upgedated wird.

    bye,
    Helmut

    Comment


    • #3
      Originally posted by hwoess View Post

      Probiere doch mal ein Update über das ManagementStudio, wo sicher nur genau ein einziger Record betroffen ist und ein Update, bei dem mehrere Records betroffen sind....
      Danke Helmut,

      für deine Antwort.
      Im "laufenden Betrieb" wird immer nur ein Datensatz geändert.
      Zum Testen des Triggers bin ich automatisch in das Management Studio gegangen und habe genau einen Wert in genau einem Datensatz geändert.
      Dabei wird dann die Fehlermeldung angezeigt.

      Es handelt sich um die Express-Version ... kann es daran liegen?


      Gruß
      Frank

      Comment


      • #4
        Nein, an der Express-Version (die verwende ich auch oft) kann es ganz sicher nicht liegen. Baue in deinen trigger mal eine Prüfung ein, ungefähr so:
        ...
        ALTER TRIGGER [dbo].[T_tbl_A]
        ON [dbo].[tbl_A]
        AFTER UPDATE
        AS

        if @@rowcount <> 1 raiserror('zu wenig/viele Records', 16, 1)

        DECLARE @ID int;
        ...

        Also gleich als erste zeile nach dem "AS"!

        bye,
        Helmut

        Comment


        • #5
          Originally posted by hwoess View Post
          if @@rowcount <> 1 raiserror('zu wenig/viele Records', 16, 1)
          Hallo Helmut,

          wenn nicht genau ein Datensatz betroffen ist, soll die Fehlermeldung kommen, wenn ich es richig verstehe.

          Diese Fehlermeldung kommt aber nicht, sondern nur die von mir beschriebene.


          Kann man das "inserted" manipulieren, bevor es ausgeführt wird? Das würde mir doch sicherlich auch helfen.

          Vielen Dank
          Frank

          Comment


          • #6
            ... und das bringt auch den Fehler:

            Code:
            DECLARE ids CURSOR FOR SELECT id FROM inserted
            DECLARE @id INT
            
            OPEN ids
            
            FETCH NEXT FROM ids INTO @id
            
            WHILE @@FETCH_STATUS = 0
            BEGIN
            	IF UPDATE (datum) UPDATE tbl_A SET update = 'TRUE' WHERE id = @id
            	FETCH NEXT FROM ids INTO @id
            END
            
            CLOSE ids

            Comment


            • #7
              Hmmm, bin gerade etwas ratlos. Wenn ich recht verstehe, gibt es im ManagementStudio keine Fehlermeldung, in deinem VisualStudio-Programm aber schon, wenn man genau denselben Record ändert?

              bye,
              Helmut

              [edit]
              ... noch was zu deinem Trigger mit dem Cursor: welches "datum" wird denn in der Abfrage geprüft? kan ja sein, dass zwei Records in "inserted" stehen, bei dem einen ist "datum" geändert, beim zweiten nicht ..
              ich würde daher eher so prüfen:
              ...
              if (select datum from inserted where id = @ids) <> (select datum from deleted where id = @ids) ...

              Comment


              • #8
                Originally posted by hwoess View Post
                Hmmm, bin gerade etwas ratlos. Wenn ich recht verstehe, gibt es im ManagementStudio keine Fehlermeldung, in deinem VisualStudio-Programm aber schon, wenn man genau denselben Record ändert?
                Hallo Helmut,

                Ich teste nur im Management-Studio. Dort erscheint auch die Fehlermeldung.
                "Fehlerquelle: Microsoft.VisualStudio.DataTools" erscheint genau dort in dieser Fehlermeldung.
                Das VisualStudio habe ich nicht installiert - nur das .NET-Framework und eine OpenSource-Entwicklungsumgebung. Ich weiß nicht, welche Teile mit dem SQL-Server zusammen installiert wurden, ob man das braucht und wie man es ausschaltet.

                Ich erstelle mal eine neue DB mit einer kleinen Tabelle zum Testen.

                Gruß
                Frank

                Comment


                • #9
                  In einer neuen Datenbank mit einer Tabelle (3 Spalten) und einem Trigger:

                  Es funktioniert!!!

                  Bei der "echten" DB gibt es einige Tabellen und viele Trigger.
                  Ich habe "das Ding" übernommen und soll es anpassen.
                  Scheinbar ist da irgendwas programmiert, was voll dazwischenhaut.

                  Wie kann man so etwas debuggen?
                  Wichtig wäre: In welcher Reihenfolge wird wo was ausgeführt und welche Zeile gibt den Fehler?


                  Vielen Dank
                  Frank

                  Comment


                  • #10
                    Probiere doch mal folgendes: du machst zuerst ein
                    "alter table meineTabelle disable trigger all"
                    dann machst du den Updatetest auf die Tabelle
                    Kommt der Fehler immer noch, hat das mit einem trigger auf diese eine tabelle nichts zu tun (die sind ja alle ausgeschaltet) und du musst mal überlegen, ob es nicht doch mit etwas anderem zu tun haben könnte. Kommt der Fehler aber nicht mehr, dann musst du dir die Trigger auf diese tabelle der Reihe nach ansehen. Kannst ja einen Trigger auch einzeln disablen/enablen. Kann natürlich zu Sideeffects führen, falls die trigger in einer bestimmten reihenfolge voneinander abhängige Sachen machen, aber das kommt selten vor und probieren geht über studieren.
                    Ach ja: alle Trigger wieder einschalten geht natürlich mit
                    "alter table meineTabelle enable trigger all"
                    Und ganz wichtig: NICHT MIT DEN ECHTDATEN AUSPROBIEREN!!!

                    bye,
                    Helmut

                    Comment


                    • #11
                      Hallo Helmut,

                      wenn ich alle Trigger dieser einen Tabelle disable, zeigt sich kein Fehler.
                      Sobald ich 'meinen' enable, kommt er wieder.

                      Ich werde die Original-DB noch mal auf einen anderen Recher Installieren und dort Schritt für Schritt diesen Trigger erstellen.

                      Auf den Original-Server habe ich von hier keinen Zugriff, so dass ich mit einer 'Kopie' arbeiten muss, aber danke für den Hinweis mit den Echtdaten.

                      Ich werde berichten.
                      Frank

                      Comment


                      • #12
                        Guten Morgen,

                        inzwischen haben wir die DB auf vier unterschiedliche Computer mit unterschiedlichen Betriebssystemen installiert ...
                        ... überall gibt es das selbe Problem ...

                        Die Lösung:
                        Es ging leider nicht anders!
                        Ich habe der Tabelle eine Auto-Inkrement-Spalte hinzugefügt und nutze nun diese ID.
                        Obwohl auch vorher immer nur ein Datensatz geändert werden sollte (die Anzahl wurde als Fehlermeldung ausgegeben), geht es nun mit der neuen ID.

                        Ich selber lege in jeder Tabelle so eine ID an, ob man sie braucht, oder nicht.
                        Das Problemprojekt habe ich nur übernommen, so dass solche Probleme, die nicht durchschaubar sind, 'vorprogrammiert' sind.

                        Danke für die Tipps und die Hilfe
                        Frank

                        Comment

                        Working...
                        X