Ankündigung

Einklappen
Keine Ankündigung bisher.

Probleme mit Trigger

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Probleme mit Trigger

    Hallo,

    ich habe eigentlich zwei verschiedene Probleme mit einer Tabelle, die aber letztlich zusammenhängen (InnoDB)

    Nr1 ist wohl ein Klassiker (evtl ein Fall für die FAQ?): Beim Einfügen eines neuen Datensatzes soll das DateTime-Feld "Erstellt" automatisch mit dem aktuellen Zeitpunkt gefüllt werden. BTW gibt es auch ein Feld "Geändert", das analog beim Ändern gefüllt werden soll. Da gibt es wohl schon Probleme, denn irgendwie klappt das mit den Standardwerten immer nur mit EINEM derartigen Feld. Wie bekommt man das hin?

    Ich habe es mit einem Trigger versucht. Dummerweise, und da kommt Problem Nr2, habe ich schon einen Trigger auf der Tabelle, der sich um andere Felder kümmert:

    Code:
    IF New.Soll = New.Haben THEN
        SIGNAL SQLSTATE '45001' SET message_text = '"Soll" und "Haben" müssen sich unterscheiden';
    END IF
    Wenn ich nun z.B. einfach

    Code:
    SET NEW.Erstellt = CURRENT_TIMESTAMP
    drüber - oder drunterschreiben will, funktioniert das nicht (habe auch mit elseif experimentiert). Dabei funzt diese Zeile für sich genommen schon. Wie bekomme ich also zwei verschiedene Aktionen gleichzeitig zum Laufen?

  • #2
    Die Prüfung ob soll und haben unterschiedlich sind macht man mit einem CHECK-Constraint.

    Code:
    test=*# create table martin66 (id int generated always as identity, soll int not null, haben int not null, erstellt timestamp default now(), geaendert timestamp default null, check (soll != haben));
    CREATE TABLE
    test=*# create function update_geaendert() returns trigger as $$begin new.geaendert = clock_timestamp(); return new; end;$$ language plpgsql;
    CREATE FUNCTION
    test=*# create trigger update_trigger before update on martin66 for each row execute procedure update_geaendert();
    CREATE TRIGGER
    test=*# \d martin66
                                        Table "public.martin66"
      Column   |            Type             | Collation | Nullable |           Default            
    -----------+-----------------------------+-----------+----------+------------------------------
     id        | integer                     |           | not null | generated always as identity
     soll      | integer                     |           | not null |
     haben     | integer                     |           | not null |
     erstellt  | timestamp without time zone |           |          | now()
     geaendert | timestamp without time zone |           |          |
    Check constraints:
        "martin66_check" CHECK (soll <> haben)
    Triggers:
        update_trigger BEFORE UPDATE ON martin66 FOR EACH ROW EXECUTE FUNCTION update_geaendert()
    
    test=*# insert into martin66 (soll, haben) values (1,2);
    INSERT 0 1
    test=*# insert into martin66 (soll, haben) values (3,3);
    FEHLER:  neue Zeile für Relation »martin66« verletzt Check-Constraint »martin66_check«
    DETAIL:  Fehlgeschlagene Zeile enthält (2, 3, 3, 2021-01-23 12:13:20.41409, null).
    test=*# select * from martin66;
     id | soll | haben |         erstellt          | geaendert
    ----+------+-------+---------------------------+-----------
      1 |    1 |     2 | 2021-01-23 12:13:20.41409 |
    (1 row)
    
    test=*# update martin66 set soll = 3 where id = 1;
    UPDATE 1
    test=*# select * from martin66;
     id | soll | haben |         erstellt          |         geaendert         
    ----+------+-------+---------------------------+---------------------------
      1 |    3 |     2 | 2021-01-23 12:13:20.41409 | 2021-01-23 13:48:55.85525
    (1 row)
    
    test=*#
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

    Kommentar


    • #3
      Super, VIELEN DANK! Check kannte ich noch nicht, damit kann ich mir so manchen Trigger sparen.

      Wie kann ich einen CHECK eigentlich in phpMyAdmin anzeigen/ändern?

      Kommentar


      • #4
        Du must jetzt leider sehr tapfer sein: MySQL kennt die Syntax von CHECK-Constraints - setzt diese dann aber nicht durch.
        PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

        Kommentar


        • #5
          umpff...
          Tatsächlich, in meinem localhost klappt es, aber das MySQL meines Providers ignoriert check....

          Bleibt mir also doch nur der Weg über Trigger. Und die ursprüngliche Fragestellung: Wie bekomme ich zwei Prüfungen in einen Trigger, etwa so:

          Code:
          IF New.Soll = New.Haben THEN
               SIGNAL SQLSTATE '45001' SET message_text = '"Soll" und "Haben" müssen sich unterscheiden';
          ELSEIF New.Soll != New.Haben THEN
              SET New.Erstellt = CURRENT_TIMESTAMP;
          END IF

          Kommentar


          • #6
            man könnte ja auch was verwenden, was funktioniert ...
            PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

            Kommentar


            • #7
              und das wäre?

              Kommentar


              • #8
                siehe meine Signature, erstes Wort.
                PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                Kommentar


                • #9
                  Da ich kein PostgreSQL verwenden kann, muss ich aufgrund deiner Aussage davon ausgehen, dass es für das Problem, das ich beschrieben habe, mit MySQL keine Lösung gibt

                  Kommentar


                  • #10
                    Du kannst das auch ausserhalb der Datenbank mit PHP abfragen, musst dann halt erst ein mal auslesen und danach eintragen, geht aber.

                    Kommentar


                    • #11
                      Zitat von protestix Beitrag anzeigen
                      Du kannst das auch ausserhalb der Datenbank mit PHP abfragen, musst dann halt erst ein mal auslesen und danach eintragen, geht aber.
                      klar, man kann sich auch mit einem Vorschlaghammer rasieren, tut zwar weh, geht aber.
                      PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                      Kommentar

                      Lädt...
                      X