将 SQL 字符串传递给 oracle 存储过程并立即执行得到结果
Pass SQL string to oracle stored procedure and get results with execute immediate
我正在尝试将 SQL 字符串传递给存储过程并使用 EXECUTE IMMEDIATE 来 return 结果。像这样:
CREATE PROCEDURE P360_RCT_COUNT (sqlString IN VARCHAR2)
AS
BEGIN
EXECUTE IMMEDIATE 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: Encountered the symbol "SELECT COUNT(ENTITY_ID),ADDR_COUNTY
FROM P360_V_RCT_COUNT GROUP " when expecting one of the following:
:= . ( @ % ; The symbol ":=" was substituted for "SELECT
COUNT(DISTINCT ENTITY_ID),ADDR_COUNTY FROM P360_V_RCT_COUNT GROUP " to
continue.
基本上,我在系统中构建一个 SQL 字符串,需要将其传递给 SP 并将结果返回给系统。我对 Oracle 中的存储过程比较陌生。
对于 return 个 OUT
参数中的值列表,您需要决定要使用的类型。
比如说,你必须 return 一些 varchar2
和一些 date
列表,你可以使用这样的东西:
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;
您可以通过这种方式测试此过程:
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_refcursor
。这可以很容易地与 JDBC 或 ODBC 一起使用。
您的程序将如下所示:
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
我正在尝试将 SQL 字符串传递给存储过程并使用 EXECUTE IMMEDIATE 来 return 结果。像这样:
CREATE PROCEDURE P360_RCT_COUNT (sqlString IN VARCHAR2)
AS
BEGIN
EXECUTE IMMEDIATE 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: Encountered the symbol "SELECT COUNT(ENTITY_ID),ADDR_COUNTY FROM P360_V_RCT_COUNT GROUP " when expecting one of the following:
:= . ( @ % ; The symbol ":=" was substituted for "SELECT COUNT(DISTINCT ENTITY_ID),ADDR_COUNTY FROM P360_V_RCT_COUNT GROUP " to continue.
基本上,我在系统中构建一个 SQL 字符串,需要将其传递给 SP 并将结果返回给系统。我对 Oracle 中的存储过程比较陌生。
对于 return 个 OUT
参数中的值列表,您需要决定要使用的类型。
比如说,你必须 return 一些 varchar2
和一些 date
列表,你可以使用这样的东西:
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;
您可以通过这种方式测试此过程:
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_refcursor
。这可以很容易地与 JDBC 或 ODBC 一起使用。
您的程序将如下所示:
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