oracle中怎么执行带有输出参数的存储过程,在程序中我知道怎么调用,

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle中怎么执行带有输出参数的存储过程,在程序中我知道怎么调用,相关的知识,希望对你有一定的参考价值。

create or replace procedure sp_pro10
(spno in number,spname out varchar2) is
begin
select ename into spname from emp where empno=spno;
end;

1、新建一个存储过程(Procedure)。

2、修改存储过程,这个存储过程有一个输入参数(pid)跟一个输出参数(name),即通过用户id查询用户名称并将名称返回。

3、调试存储过程,找到刚刚创建的存储过程右击并点击【test】选项。

4、在打开的窗口内修改id值并点击左上角的倒三角形图标开始调试。

5、按【CTRL+N】进行单步进入调试,【CTRL+O】单步调试,【CTRL+T】退出调试,也可以点击调试工具进行调试。

6、变量查看,在窗口下方可输入变量名称观察变量的变化情况。

7、调试完成后就可以检查调试结果。

参考技术A SQL> create or replace procedure sp_pro10
2 (spno in number,spname out varchar2) is
3 begin
4 select 'ename' into spname from dual;
5 end;
6 /

过程已创建。

SQL> set serveroutput on
SQL> DECLARE
2 spno number;
3 spname varchar2(10);
4 BEGIN
5 sp_pro10 (spno, spname);
6
7 dbms_output.put_line(spname);
8 END;
9 /
ename

PL/SQL 过程已成功完成。本回答被提问者和网友采纳
参考技术B --存储过程的创建
set serveroutput on;
create or replace procedure select_dept(
num_deptno in number,--定义in模式变量,要求输入部门编号
var_dname out dept.dname%type,--定义out模式变量,可以存储部门名称并输出
var_loc out dept.loc%type) is
begin
select dname,loc into var_dname,var_loc from dept
where deptno = num_deptno;--检索某个部门编号的部门信息
exception
when no_data_found then--若select语句无返回记录
dbms_output.put_line('该部门编号的不存在');--输出信息
end select_dept;
/
--存储过程的调用
--注意:含有输出参数的存储过程调用,需要先声明与out参数类型兼容的变量
set serveroutput on;
declare
var_dname dept.dname%type;
var_loc dept.loc%type;
begin
select_dept(10,var_dname,var_loc);
dbms_output.put_line(var_dname||'位于:'||var_loc);
end;
/
参考技术C 下面说明在SQL DEVELOPER中的做法,右击存储结构的文件名,在菜单中选择RUN,会跳出一个叫RUN PL/SQL的页面,在下方写着PL/SQL BLOCK 的地方修改输入参数
spno =>spno 修改为spno =>真实的值
具体可以参看HELP中的Run/Debug/Profile PL/SQL

使用 Python 和 Cx_Oracle 调用带有 XMLTYPE 输入和输出参数的 Oracle 存储过程

【中文标题】使用 Python 和 Cx_Oracle 调用带有 XMLTYPE 输入和输出参数的 Oracle 存储过程【英文标题】:Calling Oracle stored procedure with XMLTYPE input and output parameters with Python and Cx_Oracle 【发布时间】:2021-07-26 15:58:32 【问题描述】:

我正在尝试使用 Python 和 Cx_Oracle 8.2.1 运行 Oracle 存储过程。这个过程有两个 XMLTYPE 参数,一个用于输入,一个用于输出,在 Oracle 中会这样调用它并且工作正常:

DECLARE 
   RXML_OUT XMLTYPE;
BEGIN 
   RXML_OUT := NULL;
   MYPACKAGE.MYPROCEDURE ( IN_SXML, RXML_OUT );
END;

但是,我无法使用 Cx_Oracle 调用它。我试着这样称呼它:

connection = cx_Oracle.connect(config["db"]["usuario"], config["db"]["password"], 
    "/".format(config["db"]["host"], config["db"]["servicio"]), encoding=config["db"]["nls_charset"],
    nencoding=config["db"]["nls_ncharset"])

cursor = connection.cursor()

xml_in = """
    <myxml>
        <sometag>This is some XML</sometag>
    </myxml>
    """

rxml_out = cursor.var(cx_Oracle.STRING)

res = cursor.callproc('MYPACKAGE.MYPROCEDURE', [xml_in, rxml_out])[1]

我可以使用其他数据类型和常规查询运行其他程序而不会出现问题。但是,有了这个,我收到以下错误:

cx_Oracle.DatabaseError: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'MYPROCEDURE'
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'MYPROCEDURE'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

据我从文档中收集到的,Cx_Oracle 没有 XML 数据类型,如果小于 1 GB,XMLTYPE 可以被视为字符串(我正在处理的这些 XML 文件的长度最多为几 KB,所以我远远低于这个限制)。我在这里做错了什么?

更新 1

我尝试过使用临时 CLOB,as shown in the documentation here。结果是一样的(请注意,我们的DBA实际上修改了程序,只有第一个参数是XMLTYPE IN,第二个是VARCHAR OUT):

xml_in = connection.createlob(cx_Oracle.DB_TYPE_CLOB)
xml_in.write("""
    <myxml>
        <sometag>This is some XML</sometag>
    </myxml>
    """)
po_msgerror = cursor.var(cx_Oracle.STRING)

po_msgerror.setvalue(0, "")

cursor.callproc('MYPACKAGE_PKG.MYPROCEDURE', [xml_in, po_msgerror])

最终结果和之前一样:

cx_Oracle.DatabaseError: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 
'MYPROCEDURE'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

更新 2

我还尝试使用匿名 PL/SQL 块来调用过程,as shown in the documentation(与之前的代码相同,但使用 execute 方法而不是 callproc):

#cursor.callproc('MYPACKAGE_PKG.MYPROCEDURE', [xml_in, po_msgerror])
cursor.execute("""BEGIN 
        MYPACKAGE_PKG.MYPROCEDURE ( :1, :2 );
    END;
    """, [xml_in, po_msgerror])

结果还是一样:

cx_Oracle.DatabaseError: ORA-06550: line 2, column 3:
PLS-00306: wrong number or types of arguments in call to 'MYPROCEDURE'
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored

【问题讨论】:

查看cx-oracle.readthedocs.io/en/latest/user_guide/… 并使用类似的技术将数据传入,并将其作为 CLOB 取回。您可能需要从 cx_Oracle 调用的匿名 PL/SQL 块,然后调用您的过程。如果您使用可运行的示例更新您的问题(包括用于创建过程的 SQL),我们可以提供更多详细信息。 感谢克里斯托弗!我试过了(对 IN 和 OUT 参数都使用 CLOB,如您指向的文档中所示),它没有用......我将用我迄今为止尝试过的内容更新我的问题。 【参考方案1】:

经过大量的实验,我终于能够成功调用该过程并传递一个XMLTYPE输入参数。以下代码有效(该过程采用两个参数,一个 XMLTYPE IN 和一个 VARCHAR OUT):

# Consumo de package para envío del XML de prestaciones
xml_in = """
    <myxml>
        <sometag>This is some XML</sometag>
    </myxml>
    """

po_msgerror = cursor.var(cx_Oracle.STRING)
po_msgerror.setvalue(0, "")

cursor.execute("""BEGIN 
    MYPACKAGE_PKG.MYPROCEDURE ( sys.xmltype(:1), :2 );
    END;
    """, [xml_in, po_msgerror])

没有必要为 XMLTYPE IN 参数使用 CLOB,一个字符串就可以了。使用匿名 PL/SQL 块调用过程并将第一个参数显式传递为 sys.xmltype 就足够了。

我不知道是否可以以相同的方式强制转换 XMLTYPE OUT 参数并将其绑定到字符串变量。但至少对于输入参数,这工作得很好。

【讨论】:

以上是关于oracle中怎么执行带有输出参数的存储过程,在程序中我知道怎么调用,的主要内容,如果未能解决你的问题,请参考以下文章

plsql调用oracle存储过程有输入参数和输出参数 sql语句怎么写如题 谢谢了

如何通过 SQL Developer 执行带有游标和表 OUT 参数的存储过程?

如何执行存储过程

oracle中的存储过程,有啥作用,以及怎么在代码中使用?

使用 Python 和 Cx_Oracle 调用带有 XMLTYPE 输入和输出参数的 Oracle 存储过程

从 Java 调用带有数组输出参数的 Oracle 存储过程