[NEWSboard IBMi Forum]

Hybrid View

  1. #1
    Registriert seit
    Jun 2010
    Beiträge
    24

    Unhappy Stored Procedure, PHP(Extern) und das Result Set

    Hallo zusammen,

    ich rufe eine Stored Procedure auf einer iSeries V5R3 mittels PHP über ODBC auf:
    Code:
    CREATE PROCEDURE RAUSER1.RTVWTRINF (
        IN VARINPUT CHAR(20) )
        DYNAMIC RESULT SETS 1
        LANGUAGE RPGLE
        SPECIFIC RAUSER1.RTVWTRINF
        NOT DETERMINISTIC
        MODIFIES SQL DATA
        CALLED ON NULL INPUT
        EXTERNAL NAME 'RAUSER1/RTVWTRINF'
        PARAMETER STYLE GENERAL ;
    Das RPGLE Programm wird auch aufgerufen und ausgeführt. Dieses Programm soll mit Hilfe des API QSPROUTQ Informationen über eine Druckerwarteschlange zurück liefern.

    Am Ende des Programms mache ich:
    Code:
    C/exec sql                                                       
    c+   SET RESULT SETS FOR RETURN TO CLIENT ARRAY :pWtrE FOR 1 ROWS
    C/end-exec
    um mir das ermittelte Array(das auch Inhalt hat) an mein Script zurück zu geben.
    Aber im PHP kommt kein Result Set an.

    Hat vielleicht jemand eine Idee woran das liegt? Falls noch mehr Informationen benötigt werden, bitte Bescheid sagen.

    Danke schon mal für eure Hilfe.
    Last edited by bussibaer; 06-09-10 at 18:01. Grund: Smilie eingefügt
    Schönen Gruß aus Kiel

    Jörg

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Die PHP-Syntax kenn ich nicht, aber ich denke, der Unterschied liegt im Aufruf des Statements.
    Statement.Execute gibt kein Resultset zurück, Statement.Open liefert ein Resultset.
    Auch wenn du eine Prozedur aufrufst, die aber ein Resultset liefert, musst du Open verwenden.
    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
    Aug 2001
    Beiträge
    2.928
    @bussibaer:

    Siehst Du das Result Set, wenn Du die Prozedur im iSeries Navigator - Run an SQL Skript/Eine Prozedur ausführen aufrufst?

    Vielleicht hilft Dir auch der folgende Abschnitt aus der SQL Reference weiter:
    TO CLIENT
    Specifies that the cursor can return a result set to the client application. This cursor is invisible to any intermediate nested procedures. If a function or trigger called the procedure either directly or indirectly, result sets cannot be returned to the client and the cursor will be closed after the procedure finishes.

    TO CALLER
    Specifies that the cursor can return a result set to the caller of the procedure. For example, if the caller is a client application, the result set is returned to the client application.
    Birgitta
    Birgitta Hauser

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

  4. #4
    KM is offline [professional_User]
    Registriert seit
    Apr 2003
    Beiträge
    1.013
    Hallo,

    lass doch mal den Zusatz FOR RETURN TO CLIENT weg. Der Rest sieht in Ordnung aus.

    Zeige evtl. auch mal den PHP-Teil.

    Gruß,
    KM

  5. #5
    Registriert seit
    Jun 2010
    Beiträge
    24
    @Fuerchau,

    leider habe ich keine irgendwie geartete open Anweisung in der PHP-Referenz gefunden.

    @Birgitta

    Das mit dem OpsNav war eine gute Idee, wenn ich da die Prozedur aufrufe, dann erhalte ich das Result Set zurück. Ich habe vorher den SET RESULT SETS mal auf RETURN TO CALLER geändert, leider nicht bei meinem Script. Aber wenn ich das richtig in Erinnerung habe, dann kommuniziert der OpsNav über JDBC-Treiber und nicht über den ODBC-Treiber. Ich weiß nicht, ob das irgendwelchen Einfluss hat.

    @KM

    Als erstes hatte ich schon, wie von dir vorgeschlagen den SET RESULT SETS ohne das FOR RETURN TO CLIENT gemacht. Da klappte der Aufruf zumindest auch.

    Hier mal die Teile des Aufrufs:
    Nicht nervös machen lassen, ich habe den Prozedure Namen geändert, um zu sehen ob der Aufruf auch eindeutig erfolgt.
    1. Definition des Calls im Script:
    Code:
    $sql = "CALL RAUSER1.PRCWTRINF (WRITER=RAUOUT01  RAUSER1   )";
    if ( !$db->sql_procedure($sql) )
    
    /*$sql = "CALL RAUSER1.PRCWTRINF ('RAUOUT01  RAUSER1   ')";
    if ( !$db->sql_query($sql) )*/
    {
           $db_error = $db->sql_error();
           $error_status = TRUE ;
           $message[$message_counter]["errtxt"] =  $lang['error_sql'] . $db_error['message'] . "\nSQL: " .....
           $message_counter++ ;
    }
    else
    {
           $obj_array = $db->sql_fetchrow($sql_result);
           $db->sql_freeresult($sql_result);
          print_r($obj_array);
    }
    Ich habe den ERROR-Teil mal ein bisschen gekürzt, damit er hier nicht das design zerreißt.

    Das Zurück geben der Daten ist der gleiche Aufruf, den ich auch bei normalen SQL-Abfragen verwende, und die funktionieren Super.

    Hier der eigentliche Aufruf:
    Code:
    function sql_procedure($query = '')
    {
        $this->last_query_text = $query;
        $p_start = '(';
        $p_end = ')';
        $p_equal = '=';
    
        if ($query != '')
        {
            $no_parm = true;
            $parm_start = 0;
            $start_found = false;
            $parm_end = 0;
            $end_found = false;
    
            // check for parameters on string
            if ( stripos($query, $p_start) !== false )
            {
                $parm_start = stripos($query, $p_start);
                $start_found = true;
            }
            if ( stripos($query, $p_end) !== false )
            {
                $parm_end = stripos($query, $p_end);
                $end_found = true;
            }
    
            // No parameters or error on building
            if ( $start_found and $end_found )
            {
                $no_parm = false;
            }
            else
            {
                if ( !$start_found and !$end_found )
                {
                }
                else
                {
                    return false;
                }
            }
    
            if ( !$no_parm )
            {
                $var_string = substr($query, $parm_start+1, $parm_end - $parm_start - 1);
                $cmd_string = substr($query, 0, $parm_start - 1);
    
                $exp_array = explode(",", $var_string);
                $count_var = count($exp_array);
    
    
                $x = 0;
                foreach( $exp_array as $exp_element )
                {
                    $exp_element = trim($exp_element);
                    if ( stripos($exp_element, $p_equal) !== false )
                    {
                        $exp_delimiter = stripos($exp_element, $p_equal);
                        $par_array[$x] = substr($exp_element, $exp_delimiter + 1, strlen($exp_element) - $exp_delimiter - 1);
                    }
                    else
                    {
                        $par_array[$x] = '';
                    }
                    $x++;
                }
                //$this->testvar[] = $par_array;
    
                $var_string = '(';
                for( $i=1; $i <= $count_var; $i++ )
                {
                    $var_string .= '?';
                    if ( $i < $count_var )
                    {
                        $var_string .=',';
                    }
                }
                $var_string .= ')';
    
                $query = $cmd_string . ' ' . $var_string;
            }
    
                // Execute the preapare statement
            if ( ($this->prepare_result = @odbc_prepare($this->db_connect_id, $query)) === false )
            {
                $this->sql_error($query);
                $this->error_connect_id = $this->db_connect_id;
                return false;
            }
            else
            {
                if ( !$no_parm )
                {
                    if ( ($this->query_result = @odbc_execute($this->prepare_result, $par_array)) === false )
                    {
                        $this->sql_error($query);
                        $this->error_connect_id = $this->db_connect_id;
                    }
                }
                else
                {
                    if ( ($this->query_result = @odbc_execute($this->prepare_result)) === false )
                    {
                        $this->sql_error($query);
                        $this->error_connect_id = $this->db_connect_id;
                    }
                }
            }
        }
        else
        {
            return false;
        }
    
        return ($this->query_result) ? $this->query_result : false;
    }
    Schönen Gruß aus Kiel

    Jörg

  6. #6
    Registriert seit
    Jun 2010
    Beiträge
    24
    @All,

    habe eben meinen Fehler gefunden, lag wie so oft, zwischen den Ohren des Programmierers.

    Wenn ich im PHP keine Ergebniskennung ermittle, weiß das Script natürlich auch nicht, was es zurück holen soll. Außerdem habe ich festgestellt, das ich meine Procedure-Routine nicht brauche dafür. Sorry, das ich euch die Zeit gestohlen habe.
    Schönen Gruß aus Kiel

    Jörg

Similar Threads

  1. Berechtigung für Stored Procedure
    By rebe in forum NEWSboard Programmierung
    Antworten: 6
    Letzter Beitrag: 12-10-06, 11:22
  2. SET RESULT SETS
    By KM in forum NEWSboard Programmierung
    Antworten: 1
    Letzter Beitrag: 22-05-06, 14:22
  3. SQL Stored Procedure verschwindet
    By florian in forum IBM i Hauptforum
    Antworten: 10
    Letzter Beitrag: 17-05-06, 16:08
  4. Stored Procedure mit Problemen
    By peter.kinne in forum IBM i Hauptforum
    Antworten: 13
    Letzter Beitrag: 15-04-05, 09:04
  5. Löschen/Überschreiben einer Stored Procedure
    By Frank Pusch in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 13-06-01, 17:57

Berechtigungen

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