Announcement

Collapse
No announcement yet.

Problem Trigger

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

  • Problem Trigger

    Hallo zusammen,

    vermutlich bin ich blind. Ich habe einen Trigger verändert. Vorher hatte ich einen festen Trigger ohne des SQL String zu verwenden.
    Ich will den SQL Befehl im Trigger zusammensetzen je nach Übergabe der Daten. Wenn die neuen Datenfelder leer sind sollen die vorherigen Datensätze nicht mit dem leeren Inhalt überschrieben werden!
    Also baue ich den SQL String so zusammen, dass nur die Daten aktualisiert werden die auch einen gültigen Inhalt haben.
    Leider bekomme ich bei jedem Insert einen Fehler komme aber nicht dahinter wo das problem ist.

    Code:
    As
    Declare variable data integer;
    Declare variable SQL varchar(2000);
    BEGIN
    
    data = 0;
    Sql =  'UPDATE atm1 SET';
    
    if (( new.tsa_host is not null) AND (new.TSA_HOST <> 0)) then
    begin
    Sql = :Sql || ' TSA_HOST=new.TSA_HOST';data=1;
    end
    
    if (( new.CARDNUMBER is not null) AND (new.CARDNUMBER <> 0)) then
    begin
    if (data > 0) then Sql = Sql || ',';
    Sql = :Sql || ' CARDNUMBER=new.CARDNUMBER';data=1;
    end
    
    Sql = :Sql || ' WHERE TR_SEQ=new.TR_SEQ AND TR_TS>=(new.TR_TS-15.000000/1440)';
    
    if (data > 0) then execute statement :Sql;
    
    END

  • #2
    Originally posted by kandalf View Post
    Ich will den SQL Befehl im Trigger zusammensetzen je nach Übergabe der Daten. Wenn die neuen Datenfelder leer sind sollen die vorherigen Datensätze nicht mit dem leeren Inhalt überschrieben werden!
    Also baue ich den SQL String so zusammen, dass nur die Daten aktualisiert werden die auch einen gültigen Inhalt haben.
    Ich vermute mal, dass sich der Trigger auf einen INSERT-Befehl bezieht. BEFORE oder AFTER? Welche Tabelle - auf atm1?

    Leider bekomme ich bei jedem Insert einen Fehler komme aber nicht dahinter wo das problem ist.
    Unsere Aufgabe ist es offentlich, die korrekte Fehlermeldung herauszufinden.

    Hast du kontrolliert, ob der zusammengesetzte Befehl korrekt ist? Wenn du keine andere Möglichkeit hast, dann erzeuge dir eine Tabelle DebugInfo und schreib ihn dort hinein.

    Nebenbei: Code mit Einrückung ist besser zu lesen. Außerdem habe ich die Erfahrung gemacht, dass Variable besser immer mit Doppelpunkt geschrieben werden sollten (auch dann, wenn es nicht unbedingt notwendig ist):
    Code:
    if (( new.tsa_host is not null) AND (new.TSA_HOST <> 0)) then
    begin
      :Sql = :Sql || ' TSA_HOST=new.TSA_HOST';
      :data = 1;
    end
    Jürgen

    Comment


    • #3
      Ok, Code noch mal neu:

      Code:
      CREATE OR ALTER trigger atm1_ud for atm1
      active after insert position 0
      As
      Declare variable data integer;
      Declare variable SQL varchar(2000);
      BEGIN
      
      data = 0;
      Sql =  'UPDATE atm1 SET';
      
      if (( new.tsa_host is not null) AND (new.TSA_HOST <> 0)) then
      begin
          Sql = :Sql || ' TSA_HOST=new.TSA_HOST';
          data=1;
      end
      
      if (( new.CARDNUMBER is not null) AND (new.CARDNUMBER <> 0)) then
      begin
          if (:data > 0) then Sql = :Sql || ',';
              Sql = :Sql || ' CARDNUMBER=new.CARDNUMBER';
              data=1;
      end
      
      Sql = :Sql || ' WHERE TR_SEQ=new.TR_SEQ AND TR_TS>=(new.TR_TS-15.000000/1440)';
      
      if (data > 0) then execute statement :Sql;
      
      END

      Das mit dem :data = 1 geht nicht. Dann gibt es Compiler Fehlermeldungen. Variablenzuweisungen dürfen den Doppelpunkt nicht haben.

      Das mit dem SQL String in eine Tabelel schreiben ist ein guter Tip, muss ich mir mal ansehen, hast du dazu ein Beispiel?

      Fehlermeldung:
      <-206>:<335544569>:<Dynamic SQL Error. SQL error code = -206. Column unknown. NEW.TR_SEQ. At line 1, column 119>

      Köännte vielleicht wirklich sein, dass mit dem SQL String was nicht stimmt.

      Comment


      • #4
        Entschuldige meinen falschen Hinweis auf den Doppelpunkt. Da war meine Erinnerung wohl nicht sauber; ich hatte mich vor allem daran erinnert, dass ich den Doppelpunkt oft auch dort verwendet hatte, wo er nicht unbedingt nötig gewesen wäre. Aber die Fehlermeldung ist eindeutig:
        Column unknown. NEW.TR_SEQ
        Die per String erzeugte adhoc-Prozedur enthält dies als "Spalte", nicht als Wert. Lösungsvorschlag: Hinter NEW.TR_SEQ (und den anderen NEW-Angaben) verstecken sich konkrete Werte. Diese müsstest du als Wert (nicht als Spalte) in den SQL-String einbauen - etwa so:
        Code:
            Sql = :Sql || ' TSA_HOST=' || new.TSA_HOST;
        Dabei musst du natürlich zwischen Strings, Zahlen und Datumswerten unterscheiden. Außerdem ist das ein Einstieg für SQL-Injection (wahrscheinlich unproblematisch, aber du musst es zumindest im Hinterkopf beachten).

        Zur Debug-Lösung (aus MySQL kopiert, muss also vor allem hinsichtlich der ID durch eine SEQUENCE und Before-Insert-Trigger angepasst werden):
        Code:
        CREATE TABLE debuginfo (
          id INTEGER NOT NULL AUTO_INCREMENT,
          zeit TIMESTAMP,
          position INTEGER DEFAULT 0,
          text varchar(100),
          PRIMARY KEY (id)
        )
        Mit "position" wird markiert, an welcher Stelle in einem Trigger, einer StoredProcedure oder Function die Information gesammelt wird. Dort steht dann so etwas:
        Code:
          insert into debuginfo ( zeit, position, text)
          values ( current_timestamp, 1, 'erste notiz');
        Gruß Jürgen

        Comment


        • #5
          Hey, danke. Genau das habe ich auch gerade festgestellt. Da hatte ich ziemliche Knöpfe auf den Augen!!! Puh, manchmal sieht man den Wald vor lauter Bäumen nicht :-)

          Comment


          • #6
            So, erledigt.
            Funktioniert alles wie erwartet, war nur zu blöd :-(

            Comment

            Working...
            X