动态SQL主要是用于针对不同的条件或查询任务来生成不同的SQL语句。最常用的方法是直接使用EXECUTE IMMEDIATE来执行动态SQL语句字符串或字符串变量。但是对于系统自定义的包或用户自定的包其下的函数或过程,不能等同于DDL以及DML的调用,其方式稍有差异。如下见本文的描述。

有关动态SQL的描述,请参考:
           PL/SQL --> 动态SQL
           PL/SQL --> 动态SQL的常见错误

1、动态SQL调用包中过程不正确的调用方法

--演示环境
scott@USBO> select * from v$version where rownum<2;BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production--下面的调用方法不正确,收到了ORA-00900错误消息
scott@USBO> set serveroutput on;
scott@USBO> DECLARE2     v_sql   VARCHAR2 (300);3     v_tab   VARCHAR2 (30) := 'DEPT';4  BEGIN5     v_sql := 'dbms_stats.gather_table_stats(''SCOTT'',''EMP'',cascade=>true)';6     DBMS_OUTPUT.put_line (v_sql);7  8     EXECUTE IMMEDIATE v_sql;9  END;10  /
dbms_stats.gather_table_stats('SCOTT','EMP',cascade=>true)
DECLARE
*
ERROR at line 1:
ORA-00900: invalid SQL statement
ORA-06512: at line 8--下面检查一下是否是sql拼接有问题
scott@USBO> DECLARE2     v_sql   VARCHAR2 (300);3     v_tab   VARCHAR2 (30) := 'DEPT';4  BEGIN5     v_sql := 'dbms_stats.gather_table_stats(''SCOTT'',''EMP'',cascade=>true)';6     DBMS_OUTPUT.put_line (v_sql);7  8  --   EXECUTE IMMEDIATE v_sql;9  END;10  /
dbms_stats.gather_table_stats('SCOTT','EMP',cascade=>true)PL/SQL procedure successfully completed.--对于上面的SQL拼接正常,如下,直接复制输出的sql加上exec来执行成功
scott@USBO> exec dbms_stats.gather_table_stats('SCOTT','EMP',cascade=>true)PL/SQL procedure successfully completed.

2、动态SQL调用包中过程正确的调用方法

--如下面这段plsql代码,我们在原代码的基础上增加了begin ..与end部分后,该plsql块被成功执行
--注,字符拼接的plsql块中,end; 之后不需要使用斜杠“/”
scott@USBO> DECLARE2     v_sql   VARCHAR2 (300);3     v_tab   VARCHAR2 (30) := 'DEPT';4  BEGIN5     v_sql := 'begin dbms_stats.gather_table_stats(''SCOTT'',''EMP'',cascade=>true); end;';6     DBMS_OUTPUT.put_line (v_sql);7  8     EXECUTE IMMEDIATE v_sql;9  END;10  /
begin dbms_stats.gather_table_stats('SCOTT','EMP',cascade=>true); end;PL/SQL procedure successfully completed.

3、动态SQL调用包中过程带变量的情形

--下面这个示例中拼接的字串中,调用了声明中的变量
--下面给出了错误提示,是由于我们漏掉了两个单引号,即需要使用转义字符,错误如下
scott@USBO> DECLARE2     v_sql   VARCHAR2 (300);3     v_tab   VARCHAR2 (30) := 'DEPT';4  BEGIN5     v_sql := 'begin dbms_stats.gather_table_stats(''SCOTT'',' || v_tab || ',cascade=>true); end;';6     --DBMS_OUTPUT.put_line (v_sql);7  8     EXECUTE IMMEDIATE v_sql;9  END;10  /
DECLARE
*
ERROR at line 1:
ORA-06550: line 1, column 45:
PLS-00357: Table,View Or Sequence reference 'DEPT' not allowed in this context
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at line 8--下面是增加两个单引号后的情形
scott@USBO> DECLARE2     v_sql   VARCHAR2 (300);3     v_tab   VARCHAR2 (30) := 'DEPT';4  BEGIN5     v_sql := 'begin dbms_stats.gather_table_stats(''SCOTT'',''' || v_tab || ''',cascade=>true); end;';6     DBMS_OUTPUT.put_line (v_sql);7  8     EXECUTE IMMEDIATE v_sql;9  END;10  /
begin dbms_stats.gather_table_stats('SCOTT','DEPT',cascade=>true); end;PL/SQL procedure successfully completed.

4、动态SQL中调用包中函数的情形

--下面我们来调用系统包所带的函数dbms_output.put_line
--Author : Leshami
--Blog   : http://blog.csdn.net/leshamiscott@USBO> DECLARE2     v_sql   VARCHAR2 (300);3  BEGIN4     v_sql := 'begin dbms_output.put_line(''This is only a test''); end;';5  6     --DBMS_OUTPUT.put_line (v_sql);7  8     EXECUTE IMMEDIATE v_sql;9  END;10  /
This is only a testPL/SQL procedure successfully completed.--直接使用下面的方式可以实现
scott@USBO> BEGIN2     EXECUTE IMMEDIATE 'begin dbms_output.put_line(''This is only a test''); end;';3  END;4  /
This is only a testPL/SQL procedure successfully completed.

5、小结
a、对于动态SQL来调用函数,我们需要使用begin .. end来封装块,而不是简单的类似于DML以及DDL的调用方法
b、不能使用'exec pkg_name.proc_name'方式来拼接动态sql
c、可以拼接sql到变量,也可以直接将动态sql紧跟在EXECUTE IMMEDIATE,个人更倾向于使用前者

   

更多参考

DML Error Logging 特性

PL/SQL --> 游标

PL/SQL --> 隐式游标(SQL%FOUND)

批量SQL之 FORALL 语句

批量SQL之 BULK COLLECT 子句

PL/SQL 集合的初始化与赋值

PL/SQL 联合数组与嵌套表
PL/SQL 变长数组
PL/SQL --> PL/SQL记录

SQL tuning 步骤

高效SQL语句必杀技

父游标、子游标及共享游标

绑定变量及其优缺点

dbms_xplan之display_cursor函数的使用

dbms_xplan之display函数的使用

执行计划中各字段各模块描述

使用 EXPLAIN PLAN 获取SQL语句执行计划

PL/SQL -- 动态SQL调用包中函数或过程相关推荐

  1. PL/SQL -- 动态SQL

    --==================== -- PL/SQL --> 动态SQL --==================== 使用动态SQL是在编写PL/SQL过程时经常使用的方法之一.很 ...

  2. sql动态sql给变量复值_在动态SQL中使用变量

    sql动态sql给变量复值 Before we delve into these SQL concepts, note that I like to do all my development in ...

  3. Oracle 动态游标 PL/SQL 动态SQL语句 open for [using] 语句

    PL/SQL:open for [using] 语句 2017年07月19日 09:52:55 学孩儿无牙哭做粥 阅读数:681 标签: oracleSQLPLSQL 更多 个人分类: ORACLES ...

  4. 【Groovy】Groovy 动态语言特性 ( Groovy 中函数实参自动类型推断 | 函数动态参数注意事项 )

    文章目录 前言 一.Groovy 中函数实参自动类型推断 二.函数动态参数注意事项 三.完整代码示例 前言 Groovy 是动态语言 , Java 是静态语言 ; 本篇博客讨论 Groovy 中 , ...

  5. 主程序调用动态库的两种方式,动态库调用主程序的函数

    主程序调用动态库有两种方式,即隐式调用和显式调用. 隐式调用就是共享方式,程序一开始运行就调进去.在链接时候用如下的方式链接动态库:gcc -o main main.o -L./lib -ltest( ...

  6. 【Groovy】Groovy 方法调用 ( Java 中函数参数是接口类型 | 函数参数是接口类型 可以 直接传递闭包 )

    文章目录 一.Java 中函数参数是接口类型 二.函数参数是接口类型 可以 直接传递闭包 三.完整代码示例 一.Java 中函数参数是接口类型 在 Android 中经常使用如下形式的接口 : 定义一 ...

  7. java调用包中的类_java调用另一个包中的类的方法

    java调用另一个包中的类的方法 发布时间:2020-05-18 15:04:40 来源:亿速云 阅读:199 作者:小新 今天小编给大家分享的是java调用另一个包中的类的方法,相信很多人都不太了解 ...

  8. golang 同一个包中函数互相调用报错 undefined 以及在 VSCode 中配置右键执行整个包文件

    1. 代码结构 demo 文件夹下有两个文件,分别为 hello.go 和 main.go ,结构如下: wohu@wohu:~/GoCode/src$ tree demo/ demo/ ├── he ...

  9. Oracle如何限制非法调用包中过程

    原文:http://www.oracle.com/technetwork/issue-archive/2015/15-jan/o15plsql-2398996.html 假如我有一个包P_A,其中封装 ...

最新文章

  1. 沉痛悼念游戏开发大神毛星云
  2. unity渲染层级关系小结
  3. Ansible — Overview
  4. 光储充一体化充电站_【储能项目】深圳宝清240kW/500kWh光储充电站项目
  5. 干货 | 深入浅出分销体系
  6. 【Matlab】一个超简单的生成顺序数组的方法
  7. 简单判断用户重复登录,记录一下
  8. VTK:BackgroundImage背景图用法实战
  9. boost::graph模块实现双连通分量算法的测试程序
  10. 博客暂停通知-------10.1~11.24
  11. 运动基元_Java更快地对基元数组进行排序?
  12. 您准备好观看GraphQL了吗?
  13. 主板和cpu搭配表_主板和CPU如何搭配?主板和处理器搭配方法
  14. 【Hbase】HBase界面简介
  15. matlab基于瑞利信道,基于matlab的瑞利信道仿真.docx
  16. Crontab cron.deny cron.allow
  17. MIMIC数据库简介
  18. 使用Javascript实现Dropdownlist级联操作中遇到的两个错误
  19. 2023在家赚钱怎么做,有什么适合在家做的副业项目
  20. Python文字转语音文字转拼音

热门文章

  1. POJ2594 Treasure Exploration[DAG的最小可相交路径覆盖]
  2. Oracle\MS SQL Server的数据库多表关联更新UPDATE与多表更新
  3. SqlServer表死锁的解决方法
  4. Apache+MySQL+PHP安装指南
  5. asp.net 包含动态创建控件的容器如果要切换显示/隐藏不要用 Visible 属性
  6. 第二届中国云计算应用论坛圆满落幕
  7. Dom4j和Xpath(转)
  8. DLT(DeepLearningTracker)学习与代码理解 (1)
  9. 多核时代 .NET Framework 4 中的并行编程6---并行LINQ
  10. Oracle再发力,区块链平台多项更新