对于数据库项目,我需要实现一个存储过程。在我的情况下,我尝试获取指定订单的内容。我的存储过程如下所示:
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中,它还以表格形式返回所需的值:
但是现在我不知道如何将这张表放到我的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);
?>
我总是最终得到以下错误:
PLS-00306:调用&#39; BESTELLINHALT&#39;错误的参数数量或类型ORA-06550
但是程序只需要一个输入,所以我现在有点困惑。另一个错误是&#34; RTABLE&#34;在index.php&#34;中找不到。我之前从未使用过php。我的方法是基于这个论坛条目@oracle:
答案 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);
}
?>