Oracle 如何从引用游标(作为INOUT参数传递)检索数据,并从shell脚本检索到存储过程?

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脚本调用的存储过程。传递给存储过程的参数包括一个引用游标,该游标作为INOUT参数传递。我必须在执行存储过程后检索引用游标返回的数据。如何访问引用游标中的数据


提前感谢

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_行的输出。如果您想对数据做其他事情,则需要更加具体。您应该能够将光标返回到蟾蜍。