[NEWSboard IBMi Forum]
Seite 1 von 2 1 2 Letzte
  1. #1
    Registriert seit
    Sep 2004
    Beiträge
    129

    Return aus SQL Procedure

    Hallo Forum!

    Ich habe hier eine Stored Procedure die ein Insert in eine Tabelle macht.
    Wenn dort ein Fehler auftritt (Duplicate Key), wird die Procedure mit RETURN -1 verlassen.
    Ich sehe aber weder im OpsNav, StrSql oder im TestRPG diesen Wert.
    Im Joblog steht aber alles drin was ich wissen möchte.
    Habe im RPG folgendes versucht:

    exec sql
    call arupd();
    exec sql
    get diagnostics :state = return_status;

    exec sql
    call arupd();
    exec sql
    get diagnostics condition 1
    :state = returned_sqlstate,
    :code = db2_returned_sqlcode;

    Es steht überall 0 drinnen.

    Hab die Procedure geändert und einmal mit einem EXIT HANDLER, UNDO HANDLER und CONTINUE HANDLER laufen lassen, aber der Call wird immer "normal" beendet.
    Ein SIGNAL und RESIGNAL hat auch nichts gebracht.
    Was kann ich da bitte noch machen?

    LG Peter
    Wer andren eine Bratwurst brät, hat ein Bratwurstbratgerät!

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Aus einer Storedprocedure gibt es 2 Möglichkeiten einen Fehler zurückzugeben:
    Beim Aufruf "Style General" musst du eine ESC-Message an SQL (API QMHSNDPM) senden.
    Beim Aufruf "Style SQL" erhältst du weitere Aufrufparameter in deiner PLIST in denen du einen SQLCODE, SQLSTATE, MESSAGE usw. zurückgeben kannst.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    Sep 2004
    Beiträge
    129
    Die Procedure ist keine externe Procedure, sondern rein SQL.
    Laut Handbuch bedeutet ein RETURN -1, dass ein Fehler passiert ist, genau das möchte ich im RPG erfahren.
    Wer andren eine Bratwurst brät, hat ein Bratwurstbratgerät!

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Laut Handbuch musst du DB2_RETURN_STATUS
    abfragen.
    Besser scheint es aber kein RETURN zu verwenden, in diesem Fall wird SQLCODE usw. belassen:




    If a RETURN statement with a specified return value is used to return from a
    procedure then the SQLCODE, SQLSTATE, and message length in the SQLCA or
    diagnostics area are initialized to zeros, and message text is set to blanks. An
    error is not returned to the caller.

    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  5. #5
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Es gibt mehere Möglichkeiten einen Fehler zurück zu liefern.

    Probiers einfach mit folgendem Statement in deiner SQL Prozedur:
    Code:
    Signal SQLSTATE '04711'  Set Message_Text = 'Mein spezieller Fehler';
    lg Andreas

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    @Andreas
    Lies doch noch mal den Text:
    If a RETURN statement with a specified return value is used to return from a
    procedure then the SQLCODE, SQLSTATE, and message length in the SQLCA or
    diagnostics area are initialized to zeros, and message text is set to blanks
    . An
    error is not returned to the caller.


    Also entweder RETURN weglassen oder den Return-Wert weglassen!
    Ein RETURN -1 kann nur per GET DIAGNOSTIC ausgelesen werden da kein SQLCODE zurückgegeben wird.
    Das ist aber nicht "State of the art" da man normalerweise den SQLCODE abfragt (ggf. noch den SQLSTATE).
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  7. #7
    Registriert seit
    Sep 2004
    Beiträge
    129
    Habe es jetzt auch gänzlich ohne RETURN versucht, aber im RPG ist der sqlcode immer noch 0.
    Wenn ich die Procedure debugge, dann ist der sqlcode darin -803.
    Ein get diagnostics liefert ebenfalls 0 zurück.
    Im Joblog steht aber:

    Bestehender Datenbereichseintrag für einmaligen Schlüsselindex enthält
    doppelte Schlüssel.
    COMMIT-Operation schlug aufgrund der Verletzung einer Integritätsbedingung
    fehl.
    ODP nicht gelöscht.
    ODP nicht gelöscht.
    Doppelter Schlüsselwert angegeben.
    Anweisung CALL beendet.
    Anweisung GET DIAGNOSTICS beendet.
    Wer andren eine Bratwurst brät, hat ein Bratwurstbratgerät!

  8. #8
    Registriert seit
    Jan 2001
    Beiträge
    833
    Hallo,

    als Lösung bieten sich auch Ausgabeparameter an.

    z.B:
    PHP-Code:
    CREATE  PROCEDURE xyz 
    (
      
    in     pAktion        varchar 50 )  ,
      
    in     pxxx           dec 5)    ,
      
    out    pOutValue      varchar 256 ) ,
      
    out    pStatus        varchar 10 )  ,
      
    out    pStatusCode    varchar 256 )
    )          

    ...
    ...
    ...

     
    GET DIAGNOSTICS EXCEPTION 1 pStatusCode  MESSAGE_TEXT ,
                                    
    pStatus      RETURNED_SQLSTATE 
    Die Werte kann man dann im Aufrufer auswerten

    Gruß
    Michael

  9. #9
    Registriert seit
    Aug 2001
    Beiträge
    2.873
    Du must den Fehler natürlich mit SIGNAL ausgeben.
    Ein negativer SQLCODE in einem embedded SQL Programm bewirkt schließlich auch keinen Abbruch.
    Tritt der Fehler innerhalb der Prozedur auf muss er wie Andreas gezeigt hat mit SIGNAL ausgegeben werden!

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  10. #10
    Registriert seit
    Sep 2004
    Beiträge
    129
    Wenn ich den SQLSTATE mit SIGNAL zurückgeben, dann hab ich das im Joblog stehen, aber eben nicht beim GET DIAGNOSTICS.
    Was mach ich da noch falsch??

    p1: begin


    declare v_message_text varchar(128) default '';
    declare v_sqlCode integer default 0;
    declare v_sqlState char(5) default '00000';


    declare exit handler for sqlexception
    begin
    get diagnostics exception 1 v_message_text = message_text,
    v_sqlCode = db2_returned_sqlcode,
    v_sqlState = returned_sqlstate;
    rollback;
    signal sqlstate v_sqlState set message_text = v_message_text;
    end;


    delete from table
    where sonderartikel = 0;


    insert into table
    select felder from view


    end p1;

    Im RPG mach ich:

    exec sql
    call arupd();

    exec sql
    get diagnostics condition 1
    :state = returned_sqlstate,
    :code = db2_returned_sqlcode,
    :msg = message_text;

    In msg steht "Anweisung CALL beendet", state = '00000' und code = 0.

    Im Joblog steht:

    Doppelter Schlüsselwert angegeben.
    Nachricht Doppelter Schlüsselwert angegeben. wurde von SIGNAL, RESIGNAL
    oder RAISE_ERROR zurückgegeben.

    PS.: Wie fügt man denn hier so ein schönes Codefensterchen ein?
    Wer andren eine Bratwurst brät, hat ein Bratwurstbratgerät!

  11. #11
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Schalte um auf "Erweitert", da gibt's das "#" für Code-einfügen:
    Code:
      Das ist nun der Code
    Was haben denn deine aktuelle SQLCA und SQLCOD für einen Inhalt?
    Normalerweise benötigst du dafür keine Get Diagnostics.

    Und was passiert, wenn du den Exit-Handler weglässt?
    In deinem Beispiel benötigst du ihn nämlich nicht.

    Prozeduren und Funktionen sollten keinen COMMIT/ROLLBACK enthalten da damit das Transaktionshandling der Anwendung unterbrochen wird.
    Schließlich machst du ja auch keinen COMMIT im Erfolgsfall.
    Beides ist Fatal, da die Anwendung sich auf verschiedenes verlassen können muss.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  12. #12
    Registriert seit
    Sep 2004
    Beiträge
    129
    Diese Procedure ist rein zu Testzwecken, ein COMMIT wird nicht benötigt, da sie immer einen Fehler produziert.

    Ich glaube ich weiß jetzt woran es liegt.
    Die Procedure wurde mit langem Namen erstellt und als specific dann ein kurzer Systemname.
    Code:
    create procedure sp_artikelupdate_old()
      lanuage sql
      specific arupdold
    Wenn ich call arupdold() mache, bekomme ich als Rückmeldung "Anweisung CALL beendet",
    mache ich das call sp_artikelupdate_old(), bekomme ich "Doppelter Schlüsselwert angegeben".
    Hab die Procedure nochmal gelöscht, mit dem i Navigator und PDM nach Überbleibsel gesucht und alles neu erstellt, das Ergebnis ist dasselbe.
    Dazu fällt mir nur ein.
    Wer andren eine Bratwurst brät, hat ein Bratwurstbratgerät!

Similar Threads

  1. Procedure Parameterfehler - Fehlendes PTF?
    By S.Neinawaie in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 14-08-14, 08:39
  2. Problem SQL Procedure
    By CaddyMajor in forum NEWSboard Programmierung
    Antworten: 14
    Letzter Beitrag: 25-06-14, 08:22
  3. Stored Procedure endlos
    By lorenzen in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 12-12-02, 16:46
  4. Java stored procedure
    By Sven Schneider in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 03-09-02, 07:31
  5. Stored Procedure
    By lorenzen in forum IBM i Hauptforum
    Antworten: 6
    Letzter Beitrag: 27-08-02, 14:59

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •