Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将SQL字符串传递给oracle存储过程,并使用execute immediate获取结果_Sql_Oracle_Stored Procedures_Dynamic Sql - Fatal编程技术网

将SQL字符串传递给oracle存储过程,并使用execute immediate获取结果

将SQL字符串传递给oracle存储过程,并使用execute immediate获取结果,sql,oracle,stored-procedures,dynamic-sql,Sql,Oracle,Stored Procedures,Dynamic Sql,我试图将SQL字符串传递给存储过程,并使用EXECUTE IMMEDIATE返回结果。大概是这样的: CREATE PROCEDURE P360_RCT_COUNT (sqlString IN VARCHAR2) AS BEGIN EXECUTE IMMEDIATE sqlString; END; / create or replace type tabOfVarchar2 is table of varchar2(100); create or replace type tabOfDa

我试图将SQL字符串传递给存储过程,并使用EXECUTE IMMEDIATE返回结果。大概是这样的:

CREATE PROCEDURE P360_RCT_COUNT (sqlString IN VARCHAR2)
AS
BEGIN
   EXECUTE IMMEDIATE sqlString;
END;
/
create or replace type tabOfVarchar2 is table of varchar2(100);
create or replace type tabOfDates    is table of date;
create or replace procedure testProc(pString        IN     varchar2,
                                     pOutVarchar1      OUT tabOfVarchar2,
                                     pOutVarchar2      OUT tabOfVarchar2,
                                     pOutVarchar3      OUT tabOfVarchar2,
                                     pOutDates         OUT tabOfDates
                                    ) is
begin
    execute immediate pString
    bulk collect into pOutVarchar1, pOutVarchar2, pOutVarchar3, pOutDates;
end;
CREATE PROCEDURE P360_RCT_COUNT (
       sqlString IN VARCHAR2
       , p_result_set out sys_refcursor)
AS
BEGIN
   open p_result_set for sqlString;
END;
/ 
我不知道如何完成它。根据上面的说明,当我使用下面的命令执行SP时,会出现一个错误:

EXECUTE P360_RCT_COUNT 'SELECT COUNT(DISTINCT ENTITY_ID),ADDR_COUNTY FROM P360_V_RCT_COUNT GROUP BY ADDR_COUNTY';
错误是:ORA-06550:第1行第22列:

PLS-00103:遇到符号SELECT COUNTRY_ID,ADDR_COUNTY 从P360_V_RCT_COUNT GROUP开始,当预期出现以下情况之一时:

:=。@%;符号:=已替换为SELECT COUNTDISTINCT实体ID,将县从P360\u V\u RCT\u计数组添加到 继续


基本上,我正在系统中构建一个SQL字符串,需要将其传递给SP并将结果返回给系统。我对Oracle中的存储过程比较陌生。

要返回OUT参数中的值列表,需要确定要使用的类型

例如,您必须返回一些varchar2和一些日期列表,您可以使用如下内容:

CREATE PROCEDURE P360_RCT_COUNT (sqlString IN VARCHAR2)
AS
BEGIN
   EXECUTE IMMEDIATE sqlString;
END;
/
create or replace type tabOfVarchar2 is table of varchar2(100);
create or replace type tabOfDates    is table of date;
create or replace procedure testProc(pString        IN     varchar2,
                                     pOutVarchar1      OUT tabOfVarchar2,
                                     pOutVarchar2      OUT tabOfVarchar2,
                                     pOutVarchar3      OUT tabOfVarchar2,
                                     pOutDates         OUT tabOfDates
                                    ) is
begin
    execute immediate pString
    bulk collect into pOutVarchar1, pOutVarchar2, pOutVarchar3, pOutDates;
end;
CREATE PROCEDURE P360_RCT_COUNT (
       sqlString IN VARCHAR2
       , p_result_set out sys_refcursor)
AS
BEGIN
   open p_result_set for sqlString;
END;
/ 
这是测试此过程的方法:

declare
    v1   tabOfVarchar2 ;
    v2   tabOfVarchar2;
    v3   tabOfVarchar2;
    d1   tabOfDates    ;
    vSQL varchar2(100)  := 'select ''a'', ''b'', ''c'', sysdate from dual';
begin
    testProc(vSQL, v1, v2, v3, d1);
    --
    for i in v1.first .. v1.last loop
        dbms_output.put_line(v1(i) || '/' || v2(i) || '/' || v3(i) || '/' || to_char(d1(i), 'dd/mm/yyyy'));
    end loop;
end; 
其中:

a/b/c/14/04/2017

这仅适用于提供已知类型的固定列数的查询。

使用结果集的最简单方法是sys\u refcursor。这可以很容易地与JDBC或ODBC一起使用

您的过程如下所示:

CREATE PROCEDURE P360_RCT_COUNT (sqlString IN VARCHAR2)
AS
BEGIN
   EXECUTE IMMEDIATE sqlString;
END;
/
create or replace type tabOfVarchar2 is table of varchar2(100);
create or replace type tabOfDates    is table of date;
create or replace procedure testProc(pString        IN     varchar2,
                                     pOutVarchar1      OUT tabOfVarchar2,
                                     pOutVarchar2      OUT tabOfVarchar2,
                                     pOutVarchar3      OUT tabOfVarchar2,
                                     pOutDates         OUT tabOfDates
                                    ) is
begin
    execute immediate pString
    bulk collect into pOutVarchar1, pOutVarchar2, pOutVarchar3, pOutDates;
end;
CREATE PROCEDURE P360_RCT_COUNT (
       sqlString IN VARCHAR2
       , p_result_set out sys_refcursor)
AS
BEGIN
   open p_result_set for sqlString;
END;
/ 
显然,你如何称呼它的具体细节会因你的客户而异。但在SQL*Plus中,它将是:

var rc refcursor
exec P360_RCT_COUNT( 'SELECT COUNT(DISTINCT ENTITY_ID),ADDR_COUNTY FROM P360_V_RCT_COUNT GROUP BY ADDR_COUNTY', :rc);
print rc

如何返回结果?考虑查询的结果可以是单个列,不同类型的多个列,括号不是可选的:执行P360GRCTL计数“…”。但这是你最不担心的。如果存储过程除了执行SQL之外什么都不做,那么存储过程的意义是什么?直接执行SQL。如果您打算稍后添加更多处理,请注意,执行任意SQL的能力会使您面临注入攻击,而动态SQL通常是一个很难处理的问题。SP最多将返回13列。我正在使用的BPM工具没有对COUNT列执行不同查看的选项,这是我需要SP的唯一原因。我正在工具上构建SQL,只需要将其传递到SP并获取13列结果集。这里的问题是,您希望如何返回该数据?打开的光标?有13个字段的单个参数?13个不同的输出参数。。。13个不同的输出参数。请记住,此SP将始终返回超过1行。我尝试在蟾蜍中测试这一点,但我得到错误:ORA-06550:第5行,第10列:PLS-00201:标识符“TABOFDATES”必须声明为ORA-06550:第5行,第10列:PL/SQL:项忽略ORA-06550:第8行,第32列:PLS-00320:此表达式的类型声明不完整或格式错误ORA-06550:第8行,第5列:PL/SQL:语句忽略ORA-06550:第11行,第86列:PLS-00320:此表达式的类型声明不完整或格式错误ORA-06550:第11行,第9列:PL/SQL:Statement ignoredI在过程之前添加了TABOFDATES的定义;你演那个角色了吗?是的。我把所有的都加进去了。你在哪里测试这个?等等,我需要一次跑完。我能够从我的客户端运行,但现在得到一个错误:无效列类型:1111。你知道那是什么吗?现在的问题是你的客户期望什么样的结果?我定义了测试类型,但您应该首先检查客户机的测试类型