oracle 存储过程 调用动态sql

Posted Marydon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 存储过程 调用动态sql相关的知识,希望对你有一定的参考价值。

oracle 存储过程 调用动态sql

CreationTime--2018年8月16日11点25分

Author:Marydon

1.错误实现方式

--开始时间拼接\' 00:00:00\'
  V_SQL := \'select decode(length(\' || V_END || \'),10,\' || \'concat(\' || V_END || \', 00:00:00),\' || V_END || \') from dual\';
  EXECUTE IMMEDIATE V_SQL;

  编译成功,但是存储过程调用失败。

2.原因分析

  在oracl数据库中,ddl表示数据库定义语言,即我们平常使用的sql语句,声明的sql语句可以直接使用拼接字符串进行拼接;

  dml表示数据操纵语言,声明的sql语句不能再用管道符||来动态拼接变量。 

3.正确实现方式

  execute immediate属于dml,dml使用sql的规则如下:

  声明sql语句

  字符串拼接变量时,变量要使用占位符来代替,格式为 ":" + "名字",名字随意

  调用sql语句

  使用"using"来传递变量,代替占位符,格式为 "using var1,var2,..."

V_SQL := \'select decode(length(:v1),10,:v2,:v3) from dual\';
EXECUTE IMMEDIATE V_SQL INTO V_START USING V_START,V_START || \' 00:00:00\',V_START;  

  结果展示:

4.测试

  入参

  出参

5.最简单的方式

--结束时间拼接\' 00:00:00\'
SELECT DECODE(LENGTH(V_END), 10, V_END || \' 00:00:00\', V_END) INTO V_END FROM DUAL;

20200612

6.另外一种方式

  第一种字符串拼接的方式其实也是可以执行的,只不过需要借助游标来实现,这里张贴部分代码

  --业务执行
  OPEN OUT_CURSOR FOR \'SELECT TO_CHAR(TO_DATE(\' || STARTTIME || \', \'\'YYYY-MM-DD\'\') + ROWNUM - 1,
                            \'\'YYYY-MM-DD\'\') AS REGDATE
               FROM DUAL
             CONNECT BY ROWNUM <=
                        TRUNC(TO_DATE(\' || ENDTIME || \', \'\'YYYY-MM-DD\'\') -
                              TO_DATE(\' || STARTTIME || \', \'\'YYYY-MM-DD\'\')) + 1\';

  游标后面可以直接拼接SQL字符串,并将其当做SQL来执行(这是在存储过程调用的)

  结果如下

  另外对于单引号的转义,两个紧挨的单引号\'\',就表示一个转义过的单引号\' 

以上是关于oracle 存储过程 调用动态sql的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

项目开发中使用存储过程和直接使用SQL语句的区别

SQL存储过程如何调用存储过程?