Oracle [存储过程] 执行动态拼接SQL语句并返回结果??

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle [存储过程] 执行动态拼接SQL语句并返回结果??相关的知识,希望对你有一定的参考价值。

这是存储过程语句:
CREATE OR REPLACE PROCEDURE P_TEST (p_jbm in varchar2, cur_out out sys_refcursor)
IS
v_sql clob; --可能传入参数很长,超过4000个字符
Begin
v_sql := 'select t.* into cur_out from t_dtjc_zxjcjh t where t.jbm in ('||p_jbm||');';
execute immediate(v_sql);
End;

其中,p_jbm的传入值为: 'XNCVOFfeQ1','XNfB6I0cLh','XNJ4i5xkBu','XN2wG7gAYy','XNqjJMT3jd','XNrMwsqgwc','XNqRUol5Tx','XNXBJfNjcS'

通过v_sql,来创建一个可执行的SQL语句,比如这句话:
select t.* into cur_out from t_dtjc_zxjcjh t where t.jbm in ('XNCVOFfeQ1','XNfB6I0cLh','XNJ4i5xkBu','XN2wG7gAYy','XNqjJMT3jd','XNrMwsqgwc','XNqRUol5Tx','XNXBJfNjcS');

然后,让Oracle去执行,返回一个二维表。

现在的问题是:
execute immediate(v_sql);的时候,总是会报 ORA-00905 missing key
如果v_sql执行成功,怎么返回一个二维表?

参考技术A 建议你用 instr函数,v_sql条件改为
where instr(p_jbm,t.jbm)>0试试吧。追问

请问,如何将 xx,yy,zz 使用你的Instr方法转换成列?

追答

亲,不明白你的意思,
('XNCVOFfeQ1','XNfB6I0cLh','XNJ4i5xkBu','XN2wG7gAYy','XNqjJMT3jd','XNrMwsqgwc','XNqRUol5Tx','XNXBJfNjcS'),
你的意思是不是把传递过来的列转变成上述字符串?可以用wm_concat()函数

追问

不是哈,如何把传递过来的('XNCVOFfeQ1','XNfB6I0cLh','XNJ4i5xkBu','XN2wG7gAYy','XNqjJMT3jd','XNrMwsqgwc','XNqRUol5Tx','XNXBJfNjcS')这行数据转换成数据列。

追答

亲,你百度一个函数吧,将这样的字符串截取然后填到表里。
CREATE OR REPLACE FUNCTION SPLIT_STR (P_LIST VARCHAR2, P_SEP VARCHAR2)
RETURN TYPE_ARRAY
IS
i INT := 1;
j INT := 0;
LISTLEN INT := 0;
SEPLEN INT := 0;
STR VARCHAR2(200);
ARRAY_SPLIT TYPE_ARRAY := TYPE_ARRAY();
BEGIN
LISTLEN := LENGTH(P_LIST);
SEPLEN := LENGTH (P_SEP);

WHILE j = LISTLEN THEN
EXIT;
END IF;
ELSE
STR := SUBSTR(P_LIST, i, j - i);
i := j + SEPLEN;
ARRAY_SPLIT.EXTEND;
ARRAY_SPLIT(ARRAY_SPLIT.COUNT) := STR;
END IF;
END LOOP;
RETURN ARRAY_SPLIT;
END SPLIT_STR;

本回答被提问者和网友采纳

如何在oracle存储过程中执行动态sql语句

给你一个案例对这些,使用execute immediate就可以了,存储过程和语句块也是一样的,自己改一改,没区别的。

语法格式
EXECUTE IMMEDIATE dynamic_string
  [INTO define_variable[, define_variable]... | record]
  [USING [IN | OUT | IN OUT] bind_argument [, [IN | OUT | IN OUT] bind_argument]...]
  [RETURNING | RETURN INTO bind_argument[, bind_argument]...];
  
1, 操作 DDL语句,这也是动态 SQL的常用操作之一
如下所示使用动态 SQL创建 数据库表:
DECLARE
  l_dync_sql VARCHAR2(100);
BEGIN
  l_dync_sql := \'CREATE TABLE cux_dync_test(id NUMBER, creation_date DATE)\';
  EXECUTE IMMEDIATE l_dync_sql;
END;
2,操作 DML语句,使用 USING子句可以按照顺序将输入的值绑定到变量,如果动 态SQL只有单行输出的话可以直接使用 INTO来接收输出值,如下所示。
DECLARE
  l_dync_sql    VARCHAR2(100);
  l_person_name VARCHAR2(140);
  l_age         NUMBER;
BEGIN
  l_dync_sql := \'SELECT person_name, age FROM cux_cursor_test WHERE person_id = :1\';
  EXECUTE IMMEDIATE l_dync_sql
    INTO l_person_name, l_age -- 使用into语句接手动态SQL的输出,如果输出多行则出错
    USING 101; -- 给绑定变量赋值
  dbms_output.put_line(\'Person Name: \' || l_person_name);
  dbms_output.put_line(\'Age: \' || l_age);
END;
参考技术A CREATE OR REPLACE Procedure UP_ExecSqlProcForDS(strSql In Varchar2,cur_out Out sys_refcursor)AsBeginOpen cur_out ForstrSql;End;

以上是关于Oracle [存储过程] 执行动态拼接SQL语句并返回结果??的主要内容,如果未能解决你的问题,请参考以下文章

sql 存储过程如何动态拼接where后面的条件

oracle 在存储过程中用动态sql创建序列为何会遇到权限不足的问题呢?

oracle存储过程中执行查询sql语句报错

oracle 存储过程sql语句

怎样在sql语句中oracle调用存储过程

关于oracle存储过程中的sql拼接,大神进!!!