Oracle 如何从引用游标(作为INOUT参数传递)检索数据,并从shell脚本检索到存储过程?
我有一个从shell脚本调用的存储过程。传递给存储过程的参数包括一个引用游标,该游标作为INOUT参数传递。我必须在执行存储过程后检索引用游标返回的数据。如何访问引用游标中的数据Oracle 如何从引用游标(作为INOUT参数传递)检索数据,并从shell脚本检索到存储过程?,oracle,shell,Oracle,Shell,我有一个从shell脚本调用的存储过程。传递给存储过程的参数包括一个引用游标,该游标作为INOUT参数传递。我必须在执行存储过程后检索引用游标返回的数据。如何访问引用游标中的数据 提前感谢shell脚本正在连接到数据库以运行存储过程,对吗?我猜它正在使用SQL*Plus进行连接。假设游标变量是用SQL*Plus声明的,您应该能够简单地打印游标,即 SQL> create procedure return_rc( p_rc in out sys_refcursor ) 2 is 3
提前感谢shell脚本正在连接到数据库以运行存储过程,对吗?我猜它正在使用SQL*Plus进行连接。假设游标变量是用SQL*Plus声明的,您应该能够简单地打印游标,即
SQL> create procedure return_rc( p_rc in out sys_refcursor )
2 is
3 begin
4 open p_rc
5 for
6 select * from emp;
7 end;
8 /
Procedure created.
SQL> variable rc refcursor;
SQL> exec return_rc( :rc );
PL/SQL procedure successfully completed.
SQL> print rc;
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7369 smith CLERK 7902 17-DEC-80 800
20 1
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300
30 1
7521 WARD SALESMAN 7698 22-FEB-81 1250 500
30 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7566 JONES MANAGER 7839 02-APR-81 2975
20 1
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400
30 1
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10 1
7788 SCOTT ANALYST 7566 19-APR-87 3000
20 1
7839 KING PRESIDENT 17-NOV-81 5000
10 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0
30 1
7876 ADAMS CLERK 7788 23-MAY-87 1110
20 1
7900 SM2 CLERK 7698 03-DEC-81 950
30 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7902 FORD ANALYST 7566 03-DEC-81 3000
20 1
7934 MILLER CLERK 7782 23-JAN-82 1300
10 1
14 rows selected.
如果您试图获取PL/SQL块中的数据
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_rc sys_refcursor;
3 l_emprec emp%rowtype;
4 begin
5 return_rc( l_rc );
6 loop
7 fetch l_rc into l_emprec;
8 exit when l_rc%notfound;
9 dbms_output.put_line( l_emprec.ename );
10 end loop;
11 close l_rc;
12* end;
SQL> /
smith
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
SM2
FORD
MILLER
PL/SQL procedure successfully completed.
shell脚本连接到数据库是为了运行存储过程,对吗?我猜它正在使用SQL*Plus进行连接。假设游标变量是用SQL*Plus声明的,您应该能够简单地打印游标,即
SQL> create procedure return_rc( p_rc in out sys_refcursor )
2 is
3 begin
4 open p_rc
5 for
6 select * from emp;
7 end;
8 /
Procedure created.
SQL> variable rc refcursor;
SQL> exec return_rc( :rc );
PL/SQL procedure successfully completed.
SQL> print rc;
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7369 smith CLERK 7902 17-DEC-80 800
20 1
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300
30 1
7521 WARD SALESMAN 7698 22-FEB-81 1250 500
30 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7566 JONES MANAGER 7839 02-APR-81 2975
20 1
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400
30 1
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10 1
7788 SCOTT ANALYST 7566 19-APR-87 3000
20 1
7839 KING PRESIDENT 17-NOV-81 5000
10 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0
30 1
7876 ADAMS CLERK 7788 23-MAY-87 1110
20 1
7900 SM2 CLERK 7698 03-DEC-81 950
30 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO FAKE_COL FOO
---------- ---------- ----------
7902 FORD ANALYST 7566 03-DEC-81 3000
20 1
7934 MILLER CLERK 7782 23-JAN-82 1300
10 1
14 rows selected.
如果您试图获取PL/SQL块中的数据
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_rc sys_refcursor;
3 l_emprec emp%rowtype;
4 begin
5 return_rc( l_rc );
6 loop
7 fetch l_rc into l_emprec;
8 exit when l_rc%notfound;
9 dbms_output.put_line( l_emprec.ename );
10 end loop;
11 close l_rc;
12* end;
SQL> /
smith
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
SM2
FORD
MILLER
PL/SQL procedure successfully completed.
您必须编写如下代码:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read line
do
echo $line
done <${WORKDIR}/ouput_data.dat
113
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read -r impact_type_id IMPACT_TYPE_NM
do
echo $impact_type_id
echo $IMPACT_TYPE_NM
done <${WORKDIR}/ouput_data.dat
113
High
首先创建SP,如下所示:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read line
do
echo $line
done <${WORKDIR}/ouput_data.dat
113
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read -r impact_type_id IMPACT_TYPE_NM
do
echo $impact_type_id
echo $IMPACT_TYPE_NM
done <${WORKDIR}/ouput_data.dat
113
High
然后在shell脚本中按如下方式调用SP:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read line
do
echo $line
done <${WORKDIR}/ouput_data.dat
113
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read -r impact_type_id IMPACT_TYPE_NM
do
echo $impact_type_id
echo $IMPACT_TYPE_NM
done <${WORKDIR}/ouput_data.dat
113
High
如果要从SP输出读取特定字段,请参阅以下代码:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id as impact_type_id,IMPACT_TYPE_NM as IMPACT_TYPE_NM,SEVERITY_ORDER as SEVERITY_ORDER
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
然后在shell脚本中按如下方式调用SP:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read line
do
echo $line
done <${WORKDIR}/ouput_data.dat
113
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read -r impact_type_id IMPACT_TYPE_NM
do
echo $impact_type_id
echo $IMPACT_TYPE_NM
done <${WORKDIR}/ouput_data.dat
113
High
您必须编写如下代码:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read line
do
echo $line
done <${WORKDIR}/ouput_data.dat
113
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read -r impact_type_id IMPACT_TYPE_NM
do
echo $impact_type_id
echo $IMPACT_TYPE_NM
done <${WORKDIR}/ouput_data.dat
113
High
首先创建SP,如下所示:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read line
do
echo $line
done <${WORKDIR}/ouput_data.dat
113
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read -r impact_type_id IMPACT_TYPE_NM
do
echo $impact_type_id
echo $IMPACT_TYPE_NM
done <${WORKDIR}/ouput_data.dat
113
High
然后在shell脚本中按如下方式调用SP:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read line
do
echo $line
done <${WORKDIR}/ouput_data.dat
113
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read -r impact_type_id IMPACT_TYPE_NM
do
echo $impact_type_id
echo $IMPACT_TYPE_NM
done <${WORKDIR}/ouput_data.dat
113
High
如果要从SP输出读取特定字段,请参阅以下代码:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id as impact_type_id,IMPACT_TYPE_NM as IMPACT_TYPE_NM,SEVERITY_ORDER as SEVERITY_ORDER
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
然后在shell脚本中按如下方式调用SP:-
create or replace PROCEDURE impact_type_test
(
v_impact_type_id IN NUMBER,
cv_1 OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN cv_1 FOR
SELECT impact_type_id
FROM impact_type
WHERE impact_type_id = v_impact_type_id ;
END;
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read line
do
echo $line
done <${WORKDIR}/ouput_data.dat
113
sqlplus -S /nolog <<-! >/dev/null 2>&1
connect ${ORACLE_UID}/${ORACLE_PWD}@${ORACLE_DB};
whenever sqlerror exit sql.sqlcode;
set heading off
set verify off
set feedback off
set pagesize 0
set linesize 150
spool ${WORKDIR}/ouput_data.dat
var vc refcursor;
execute impact_type_test (1,:vc);
print vc;
spool off;
exit
!
while read -r impact_type_id IMPACT_TYPE_NM
do
echo $impact_type_id
echo $IMPACT_TYPE_NM
done <${WORKDIR}/ouput_data.dat
113
High
谢谢。实际上,我正在尝试在PL SQL块中执行一个过程。代码类似于DECLARE cursor refcursor;BEGIN-procedure现在我想显示inout参数,即PLSQL块内的引用光标。但是有了上面的代码,我不能这么做Hi Justin..谢谢..但我有一个疑问。在第3行中,emp是表名,ename是表中的一列,rite?我用一张临时桌子代替。我在第7行出错了。它说ORA-06504:PL/SQL:Result Set variables或query的返回类型与ORA-06512:at line 7不匹配,可能是什么问题?嗨..我发现了问题。游标没有返回表中的所有列。我如何克服这种情况?我正在用蟾蜍处死。恐怕dbms_output.put_行在toad中不起作用。如何获得输出?就像任何游标一样,您需要声明变量以获取数据。无论过程选择什么列,都需要在PL/SQL块中声明以获取。蟾蜍应该能够显示dbms_output.put_行的输出。如果您想对数据做其他事情,则需要更加具体。您应该能够将游标返回给Toad.Thank。实际上,我正在尝试在PL SQL块中执行一个过程;BEGIN-procedure现在我想显示inout参数,即PLSQL块内的引用光标。但是有了上面的代码,我不能这么做Hi Justin..谢谢..但我有一个疑问。在第3行中,emp是表名,ename是表中的一列,rite?我用一张临时桌子代替。我在第7行出错了。它说ORA-06504:PL/SQL:Result Set variables或query的返回类型与ORA-06512:at line 7不匹配,可能是什么问题?嗨..我发现了问题。游标没有返回表中的所有列。我如何克服这种情况?我正在用蟾蜍处死。恐怕dbms_output.put_行在toad中不起作用。如何获得输出?就像任何游标一样,您需要声明变量以获取数据。无论过程选择什么列,都需要在PL/SQL块中声明以获取。蟾蜍应该能够显示dbms_output.put_行的输出。如果您想对数据做其他事情,则需要更加具体。您应该能够将光标返回到蟾蜍。