2016-01-20 3 views
0

для проекта базы данных Мне нужно реализовать хранимую процедуру. В моем случае я пытаюсь получить содержимое определенного порядка. Моя хранимая процедура выглядит следующим образом:Как вернуть таблицу из хранимой процедуры в PHP

create or replace PROCEDURE bestellinhalt (sbestellnr IN integer, rtable OUT sys_refcursor) IS 
BEGIN 
    OPEN rtable for SELECT beinhaltet.bestellnr,artikel.artikelname, artikel.artikelnr, beinhaltet.anzahl, artikel.preis FROM ARTIKEL, BEINHALTET WHERE ARTIKEL.ARTIKELNR = BEINHALTET.ARTIKELNR AND BEINHALTET.BESTELLNR = sbestellnr; 
END; 

И в SQL Developer также возвращает нужное значение в виде таблицы:

Output of SQL Developer

Но теперь я не имею ни малейшего представления, как я могу получить эту таблицу на моей странице PHP. Это, как я попробовал:

<?php 
    //Handle Stored Procedure 
    if (isset($_GET['bestellnr'])) 
    { 
     //Call Stored Procedure 
     $bestellnr = intval($_GET['bestellnr']); 
     $sproc = oci_parse($conn, 'begin bestellinhalt(:in, :rtable); end;'); 
     $returntable = oci_new_collection($conn, 'RTABLE'); 
     //Bind variables, p1=input (nachname), p2=output (abtnr) 
     oci_bind_by_name($sproc, ':in', $bestellnr); 
     oci_bind_by_name($sproc, ':rtable', $returntable); 
     oci_execute($sproc); 
     $conn_err=oci_error($conn); 
     $proc_err=oci_error($sproc); 
     //If there have been no Connection or Database errors, print department 
     if(!$conn_err && !$proc_err){ 
      echo("Erfolg"); // prints OUT parameter of stored procedure 
     } 
     else{ 
      //Print potential errors and warning 
      echo("Fehler!"); 
      print($conn_err); 
      print_r($proc_err); 
     } 
    } 
    // clean up connections 
    oci_free_statement($sproc); 
    oci_close($conn); 
    ?> 

I Allways заканчиваясь со следующей ошибкой:

PLS-00306: wrong number or types of arguments in call to 'BESTELLINHALT' ORA-06550

Но процедура ожидает только один вход, так что сейчас я немного запутался. Другая ошибка «RTABLE» не найден в index.php»Я никогда не использовал PHP, прежде чем мой подход основан на этом форуме въездной @oracle:...

https://community.oracle.com/thread/617612?tstart=0

ответ

1

Пожалуйста, внимательно прочтите эту страницу я есть все ответы вам нужно.

http://www.oracle.com/technetwork/articles/fuecks-sps-095636.html

и Цитируя той же странице ответ.

CREATE OR REPLACE PACKAGE BODY blog AS 

    /*------------------------------------------------*/ 
    PROCEDURE latest(
     num_entries_in IN NUMBER, 
     entries_cursor_out OUT cursorType 
    ) AS 

     BEGIN 

      OPEN entries_cursor_out FOR 
       SELECT * FROM blogs WHERE rownum < num_entries_in 
       ORDER BY date_published DESC; 

     END latest; 

    /*------------------------------------------------*/ 
    PROCEDURE edit_entry(
     status_out OUT NUMBER, 
     status_msg_out OUT VARCHAR2, 
     id_inout IN OUT INTEGER, 
     title_in IN VARCHAR2, 
     text_out OUT CLOB, 
     categories_in IN list_of_numbers 
    ) AS 

     ENTRY_NOT_FOUND EXCEPTION; 
     entry_found INTEGER := 0; 

     BEGIN 

      /* Default status to success */ 
      status_out := 1; 

      /* If id_inout has a value then attempt to UPDATE */ 
      IF id_inout IS NOT NULL THEN 

       /* Check the id exists - raise ENTRY_NOT_FOUND if not */ 
       SELECT COUNT(*) INTO entry_found 
       FROM blogs b WHERE b.id = id_inout; 
       IF entry_found != 1 THEN RAISE ENTRY_NOT_FOUND; END IF; 

       /* Update the blogs table returning the CLOB field */ 
       UPDATE blogs b SET b.title = title_in, b.text = EMPTY_CLOB() 
       WHERE b.id = id_inout RETURNING b.text INTO text_out; 

       /* Remove any existing relationships to categories 
        - new categories inserted below */ 
       DELETE FROM blogs_to_categories WHERE blog_id = id_inout; 

       status_msg_out := 'Blog entry ' || id_inout || ' updated'; 

      /* id_inout was null so INSERT new record */ 
      ELSE 

       INSERT INTO blogs b (b.id, b.title, b.date_published, b.text) 
       VALUES (blog_id_seq.nextval, title_in, SYSDATE, EMPTY_CLOB()) 
       RETURNING b.id, b.text INTO id_inout, text_out; 

       status_msg_out := 'Blog entry ' || id_inout || ' inserted'; 

      END IF; 

      /* Now handle assignment to categories. 
       Loop over the categories_in collection, 
       inserting the new category assignments */ 
      FOR i IN 1 .. categories_in.count 
       LOOP 
        INSERT INTO blogs_to_categories (blog_id,category_id) 
        VALUES (id_inout,categories_in(i)); 
       END LOOP; 

      status_msg_out := status_msg_out || ' - added to ' 
           || categories_in.count || ' categories'; 

      EXCEPTION 
       /* Catch the exception when id_inout not found */ 
       WHEN ENTRY_NOT_FOUND THEN 
        status_out := -1001; 
        status_msg_out := 'No entry found in table blogs with id = ' 
             || id_inout; 
       /* Catch any other exceptions raised by Oracle */ 
       WHEN OTHERS THEN 
        status_out := -1; 
        status_msg_out := 'Error: ' || TO_CHAR (SQLCODE) || SQLERRM; 

     END edit_entry; 

END blog; 
/

The underlying table structure the procedures are using is: 

CREATE SEQUENCE blog_id_seq 
    INCREMENT BY 1; 
/
CREATE TABLE blogs (
    id NUMBER PRIMARY KEY, 
    title VARCHAR2(200), 
    date_published DATE, 
    text CLOB 
); 
/
CREATE SEQUENCE category_id_seq 
    INCREMENT BY 1; 

CREATE TABLE categories (
    id NUMBER PRIMARY KEY, 
    name VARCHAR2(30) UNIQUE 
); 
/
CREATE TABLE blogs_to_categories (
    blog_id INTEGER NOT NULL 
    REFERENCES blogs(id), 
    category_id INTEGER NOT NULL 
    REFERENCES categories(id), 
    PRIMARY KEY (blog_id, category_id) 
); 
/

Stored Procedures and Reference Cursors 

Looking at the blog.latest procedure, you'll see it returns a reference cursor for iterating over the row in my blogs table. 

To work with a cursor in PHP two additional steps are required, as compared to accessing rows directly from a SELECT statement. The first step is preparing a cursor resource in PHP, using the oci_new_cursor() function, which you then use to bind to the appropriate parameter. The second step, after you have executed the SQL statement, is calling oci_execute() on the cursor resource. 

The following PHP script illustrates this procedure: 

<?php 
$conn = oci_connect('SCOTT','TIGER') or die; 


$sql = 'BEGIN blog.latest(:num_entries, :blog_entries); END;'; 

$stmt = oci_parse($conn, $sql); 

// Bind the input num_entries argument to the $max_entries PHP variable 
$max_entries = 5; 
oci_bind_by_name($stmt,":num_entries",$max_entries,32); 

// Create a new cursor resource 
$blog_entries = oci_new_cursor($conn); 

// Bind the cursor resource to the Oracle argument 
oci_bind_by_name($stmt,":blog_entries",$blog_entries,-1,OCI_B_CURSOR); 

// Execute the statement 
oci_execute($stmt); 

// Execute the cursor 
oci_execute($blog_entries); 

print "The $max_entries most recent blog entries\n"; 

// Use OCIFetchinto in the same way as you would with SELECT 
while ($entry = oci_fetch_assoc($blog_entries, OCI_RETURN_LOBS)) { 
    print_r($entry); 
} 
?> 
+0

Спасибо за ответ, я буду попробуйте реализовать его, как описано на странице. – Cracksoldier

+0

Спасибо за вашу помощь, теперь он работает, ты мой герой. – Cracksoldier

Смежные вопросы