1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Trigger mit UPDATE() Bedingung feuert bei NULL-Wert

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von ukulele, 10 Februar 2011.

  1. ukulele

    ukulele Datenbank-Guru

    Hallo Forum, ich hoffe ich finde hier dauerhaft Unterstützung zu den unzähligen SQL Merkwürdigkeiten in meinem Dasein ;).

    Folgendes Szenario (stark vereinfacht):

    Tabellen:
    A, B, C
    Spalten in A:
    insert_value_in_B varchar NULL
    insert_value_in_C varchar NULL
    Spalten in B:
    value_in_B varchar NOT NULL
    Spalten in C:
    value_in_C varchar NOT NULL
    Trigger:
    trigger_a
    trigger_b

    Trigger a und b haben die selbe Funktionsweise.
    PHP:
    AFTER UPDATEINSERT
    AS
    IF        
    UPDATE(insert_value_in_X)
    BEGIN
               Schreibe insert_value_in_X in Tabelle X
    END
    Erstelle ich jetzt einen neuen Eintrag mit einem Wert in insert_value_in_B trägt Trigger B diesen Wert in der Tabelle B ein. Trigger A und Tabelle A bleiben untätig. Versuche ich nur in A einen Eintrag zu schreiben reagiert Trigger B und versucht einen NULL-Wert in Tabelle B zu schreiben. Die Trigger sind wie gesagt vom Aufbau her nahezu identisch. Ich habe nun noch eine IF Abfrage auf NULL Werte in B eingebaut, klappt auch, aber das ganze ergibt für mich keinen Sinn. Hat jemand eine Idee?
     
  2. Charly

    Charly Datenbank-Guru

    AW: Trigger mit UPDATE() Bedingung feuert bei NULL-Wert

    Hallo ukulele,

    kannst Du die Original Create-Anweisungen der Tabellen und Trigger einstellen.

    So wie Du das dargestellt hast kann ich den Fehler nicht finden.

    Gruß Charly

    PS: Sorry für die späte Antwort.
     
  3. ukulele

    ukulele Datenbank-Guru

    AW: Trigger mit UPDATE() Bedingung feuert bei NULL-Wert

    Soooo hat etwas gedauert bis ich mich nochmal mit dem Problem auseinander gesetzt habe. Ich bin durch Zufall auf den Unterschied in beiden Triggern aufmerksam geworden, siehe Makierung. Allerdings besteht das Problem weiterhin, denn beide Trigger scheinen damit auf NULL-Werte zu reagieren.

    Folgendes sei noch gesagt: Ich habe quasi "Hilfsspalten" in meine Haupttabelle eingebaut um Werte aus meiner Eingabemaske in der Anwendung per Trigger in die Nebentabellen zu schreiben. Ist sicher DB technisch wenig elegant aber bequemer für den Nutzer. Alle Spalten Namens "insert_xxx" sind nichts weiter als leere Hilfsspalten zu diesem Zweck. Die Werte werden dann in gleichnamige Spalten (ohne insert_) in die Nebentabelle geschrieben und danach gelöscht.

    PHP:
    CREATE TRIGGER    [dbo].[unt_insert_into_ruf]
        
    ON            [dbo].[unt]
        
    AFTER UPDATEINSERT
    AS
    IF        
    UPDATE(insert_ruf_nummer)
    -- 
    Komischer FehlerTrigger auf UPDATE() reagiert auf NULL,
    -- 
    daher Behelfslösung
    -- AND (    SELECT    insert_ruf_nummer
    --        FROM    INSERTED IS NOT NULL
    BEGIN
            SET NOCOUNT ON
    ;

            DECLARE    @
    pk UNIQUEIDENTIFIER
            
    DECLARE    @insert_ruf_ort VARCHAR(10)
            DECLARE    @
    insert_ruf_nummer VARCHAR(20)
            DECLARE    @
    insert_ruf_durchwahl VARCHAR(6)
            DECLARE    @
    insert_ruf_typ_anschluss VARCHAR(21)
            DECLARE    @
    insert_ruf_typ_geraet VARCHAR(20)
            DECLARE    @
    insert_ruf_typ_outlook VARCHAR(20)
            DECLARE    @
    insert_ruf_quelle VARCHAR(20)
            DECLARE    @
    insert_ruf_von DATETIME
            
    DECLARE    @insert_ruf_fk_per UNIQUEIDENTIFIER
            
    DECLARE    @insert_ruf_fk_adr UNIQUEIDENTIFIER
            
    DECLARE    @error VARCHAR(255)

            
    SELECT    @pk pk,
                    @
    insert_ruf_ort insert_ruf_ort,
                    @
    insert_ruf_nummer insert_ruf_nummer,
                    @
    insert_ruf_durchwahl insert_ruf_durchwahl,
                    @
    insert_ruf_typ_anschluss insert_ruf_typ_anschluss,
                    @
    insert_ruf_typ_geraet insert_ruf_typ_geraet,
                    @
    insert_ruf_typ_outlook insert_ruf_typ_outlook,
                    @
    insert_ruf_quelle insert_ruf_quelle,
                    @
    insert_ruf_von insert_ruf_von,
                    @
    insert_ruf_fk_per insert_ruf_fk_per,
                    @
    insert_ruf_fk_adr insert_ruf_fk_adr
            FROM    INSERTED

            
    IF        @insert_ruf_typ_outlook IS NOT NULL
    --Zusätzliche Abfrage, die das Problem mit den NULL-Werten bisher scheinbar verhindert hat.
            AND (    
    SELECT    count(*)
                    
    FROM    ruf
                    WHERE    fk_unt 
    = @pk
                    
    AND (    fk_per = @insert_ruf_fk_per
                    
    OR        fk_per IS NULL )
                    AND        
    typ_outlook = @insert_ruf_typ_outlook
                    
    AND (    ungueltig 0
                    
    OR        ungueltig IS NULL )
                    AND (    
    bis getdate()
                    OR        
    bis IS NULL ) ) > 0
            BEGIN
                    SET        
    @error =    'Im zugehörigen Outlook Kontakt ist bereits eine gültige Rufnummer als "' +
                                        @
    insert_ruf_typ_outlook '" eingetragen.'
                    
    RAISERROR(@error,16,1)
            
    END
            
    ELSE
                    
    INSERT INTO    ruf(pk,fk_unt,land,ort,nummer,durchwahl,typ_anschluss,typ_geraet,
                                
    typ_outlook,quelle,von,fk_per,fk_adr)
                    
    VALUES(    newid(),@pk,'0049',@insert_ruf_ort,@insert_ruf_nummer,@insert_ruf_durchwahl,
                            @
    insert_ruf_typ_anschluss,@insert_ruf_typ_geraet,@insert_ruf_typ_outlook,
                            @
    insert_ruf_quelle,@insert_ruf_von,@insert_ruf_fk_per,@insert_ruf_fk_adr)
                    
                    
    UPDATE    unt
                    SET        insert_ruf_ort 
    NULL,
                            
    insert_ruf_nummer NULL,
                            
    insert_ruf_durchwahl NULL,
                            
    insert_ruf_typ_anschluss NULL,
                            
    insert_ruf_typ_geraet NULL,
                            
    insert_ruf_typ_outlook NULL,
                            
    insert_ruf_quelle NULL,
                            
    insert_ruf_von NULL,
                            
    insert_ruf_fk_per NULL,
                            
    insert_ruf_fk_adr NULL
                    WHERE    pk 
    = @pk
    END
    GO
    PHP:
    CREATE TRIGGER    [dbo].[unt_insert_into_adr]
        
    ON            [dbo].[unt]
        
    AFTER UPDATEINSERT
    AS
    IF        
    UPDATE(insert_adr_ort)
    -- 
    Komischer FehlerTrigger auf UPDATE(insert_adr_ortreagiert auf NULL,
    -- 
    daher Behelfslösung
    AND (    SELECT    insert_adr_ort
            FROM    INSERTED 
    IS NOT NULL
    BEGIN
            SET NOCOUNT ON
    ;

            DECLARE    @
    pk UNIQUEIDENTIFIER
            
    DECLARE    @insert_adr_strasse VARCHAR(40)
            DECLARE    @
    insert_adr_hausnr VARCHAR(8)
            DECLARE    @
    insert_adr_plz VARCHAR(8)
            DECLARE    @
    insert_adr_ort VARCHAR(40)
            DECLARE    @
    insert_adr_von DATETIME
            
    DECLARE    @insert_adr_typ VARCHAR(20)
            DECLARE    @
    insert_adr_quelle VARCHAR(20)
            DECLARE    @
    error VARCHAR(255)

            
    SELECT    @pk pk,
                    @
    insert_adr_strasse insert_adr_strasse,
                    @
    insert_adr_hausnr insert_adr_hausnr,
                    @
    insert_adr_plz insert_adr_plz,
                    @
    insert_adr_ort insert_adr_ort,
                    @
    insert_adr_von insert_adr_von,
                    @
    insert_adr_typ insert_adr_typ,
                    @
    insert_adr_quelle insert_adr_quelle
            FROM    INSERTED

            
    IF (    SELECT    count(*)
                    
    FROM    adr
                    WHERE    fk_unt 
    = @pk
                    
    AND        typ = @insert_adr_typ
                    
    AND (    quelle = @insert_adr_quelle
                    
    OR        quelle IS NULL )
                    AND (    
    ungueltig 0
                    
    OR        ungueltig IS NULL )
                    AND (    
    bis getdate()
                    OR        
    bis IS NULL ) ) > 0
            BEGIN
                    SET        
    @error =    'Es liegt Bereits eine derzeit gültige Adresse' +
                                        ( CASE 
    WHEN @insert_adr_typ IS NOT NULL THEN ' Typ ' + @insert_adr_typ ELSE '' END ) +
                                        ( CASE 
    WHEN @insert_adr_quelle IS NOT NULL THEN ' Quelle ' + @insert_adr_quelle ELSE '' END ) +
                                        
    ' vor. Bitte prüfen Sie die vorhandenen Unternehmensbezeichnungen.'
                    
    RAISERROR (@error,16,1)
            
    END
            
    ELSE
                    
    INSERT INTO    adr(pk,fk_unt,strasse,hausnr,plz,ort,von,typ,quelle)
                    
    VALUES(    newid(),@pk,@insert_adr_strasse,@insert_adr_hausnr,@insert_adr_plz,
                            @
    insert_adr_ort,@insert_adr_von,@insert_adr_typ,@insert_adr_quelle)
                    
                    
    UPDATE    unt
                    SET        insert_adr_strasse 
    NULL,
                            
    insert_adr_hausnr NULL,
                            
    insert_adr_plz NULL,
                            
    insert_adr_ort NULL,
                            
    insert_adr_von NULL,
                            
    insert_adr_typ NULL,
                            
    insert_adr_quelle NULL
                    WHERE    pk 
    = @pk
    END
    GO
     
  4. ukulele

    ukulele Datenbank-Guru

    AW: Trigger mit UPDATE() Bedingung feuert bei NULL-Wert

    [FONT=Verdana, Arial, Helvetica, sans-serif][FONT=Verdana, Arial, Helvetica, sans-serif]"One thing I haven't mentioned so far is the difference between a column being updated and a column being changed. An update occurs when you "set" a column to a value, even if it's the same value that already existed! I think many people mistake update triggers for "change" triggers. If you want to execute code only if something has changed, then you have to do the comparison in the where clause." so so...

    Verzichte ich auf die UPDATE() Funktion und arbeite mit einer IF Abfrage auf einen Eintrag in der Spalte funktioniert das natürlich tadelos. Da aber 2 Trigger am Werk sind feuern diese rekursiv. Alles in einen AFTER Trigger zu bauen scheint eine Lösung, wird aber irgendwann unübersichtlich. Für Alternativen bin ich dankbar.[/FONT][/FONT]
     
  5. ukulele

    ukulele Datenbank-Guru

    AW: Trigger mit UPDATE() Bedingung feuert bei NULL-Wert

    Okay es ist nicht der Unterschied der beiden Trigger, es sind die Trigger der Zieltabellen die das ganze rekursiv feuern lassen. (Die Nebentabellen schreiben zurück in andere Spalten der Haupttabelle). :(

    Ich debugge mal weiter...
     
  6. Charly

    Charly Datenbank-Guru

    AW: Trigger mit UPDATE() Bedingung feuert bei NULL-Wert

    Hallo ukulele,

    die Idee mit einem Trigger scheint mir in Anbetracht der Tatsache das beide Trigger auf der gleichen Tabelle sitzen durchaus sinnvoll.

    Ich hab mich mal durch Deine Trigger gearbeitet.

    Der ELSE Teil der inneren IF löst meiner Meinung auf jeden Fall den anderen Trigger aus (wegen dem Update auf unt). Dann schreibt Trigger B halt die NULL-Werte aus Deinem Update Befehl aus Trigger A in die Tabelle.

    Alternativ könntest Du die Insert- und Update-Logik auch in Prozeduren packen. 4 Prozeduren (Jeweils eine pro Tabelle für UPDATE und INSERT). So was mache ich gerne.


    Gruß Charly
     
Die Seite wird geladen...

Diese Seite empfehlen