PL/SQL -- 动态SQL调用包中函数或过程
动态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调用包中函数或过程相关推荐
- PL/SQL -- 动态SQL
--==================== -- PL/SQL --> 动态SQL --==================== 使用动态SQL是在编写PL/SQL过程时经常使用的方法之一.很 ...
- sql动态sql给变量复值_在动态SQL中使用变量
sql动态sql给变量复值 Before we delve into these SQL concepts, note that I like to do all my development in ...
- Oracle 动态游标 PL/SQL 动态SQL语句 open for [using] 语句
PL/SQL:open for [using] 语句 2017年07月19日 09:52:55 学孩儿无牙哭做粥 阅读数:681 标签: oracleSQLPLSQL 更多 个人分类: ORACLES ...
- 【Groovy】Groovy 动态语言特性 ( Groovy 中函数实参自动类型推断 | 函数动态参数注意事项 )
文章目录 前言 一.Groovy 中函数实参自动类型推断 二.函数动态参数注意事项 三.完整代码示例 前言 Groovy 是动态语言 , Java 是静态语言 ; 本篇博客讨论 Groovy 中 , ...
- 主程序调用动态库的两种方式,动态库调用主程序的函数
主程序调用动态库有两种方式,即隐式调用和显式调用. 隐式调用就是共享方式,程序一开始运行就调进去.在链接时候用如下的方式链接动态库:gcc -o main main.o -L./lib -ltest( ...
- 【Groovy】Groovy 方法调用 ( Java 中函数参数是接口类型 | 函数参数是接口类型 可以 直接传递闭包 )
文章目录 一.Java 中函数参数是接口类型 二.函数参数是接口类型 可以 直接传递闭包 三.完整代码示例 一.Java 中函数参数是接口类型 在 Android 中经常使用如下形式的接口 : 定义一 ...
- java调用包中的类_java调用另一个包中的类的方法
java调用另一个包中的类的方法 发布时间:2020-05-18 15:04:40 来源:亿速云 阅读:199 作者:小新 今天小编给大家分享的是java调用另一个包中的类的方法,相信很多人都不太了解 ...
- golang 同一个包中函数互相调用报错 undefined 以及在 VSCode 中配置右键执行整个包文件
1. 代码结构 demo 文件夹下有两个文件,分别为 hello.go 和 main.go ,结构如下: wohu@wohu:~/GoCode/src$ tree demo/ demo/ ├── he ...
- Oracle如何限制非法调用包中过程
原文:http://www.oracle.com/technetwork/issue-archive/2015/15-jan/o15plsql-2398996.html 假如我有一个包P_A,其中封装 ...
最新文章
- 沉痛悼念游戏开发大神毛星云
- unity渲染层级关系小结
- Ansible — Overview
- 光储充一体化充电站_【储能项目】深圳宝清240kW/500kWh光储充电站项目
- 干货 | 深入浅出分销体系
- 【Matlab】一个超简单的生成顺序数组的方法
- 简单判断用户重复登录,记录一下
- VTK:BackgroundImage背景图用法实战
- boost::graph模块实现双连通分量算法的测试程序
- 博客暂停通知-------10.1~11.24
- 运动基元_Java更快地对基元数组进行排序?
- 您准备好观看GraphQL了吗?
- 主板和cpu搭配表_主板和CPU如何搭配?主板和处理器搭配方法
- 【Hbase】HBase界面简介
- matlab基于瑞利信道,基于matlab的瑞利信道仿真.docx
- Crontab cron.deny cron.allow
- MIMIC数据库简介
- 使用Javascript实现Dropdownlist级联操作中遇到的两个错误
- 2023在家赚钱怎么做,有什么适合在家做的副业项目
- Python文字转语音文字转拼音
热门文章
- POJ2594 Treasure Exploration[DAG的最小可相交路径覆盖]
- Oracle\MS SQL Server的数据库多表关联更新UPDATE与多表更新
- SqlServer表死锁的解决方法
- Apache+MySQL+PHP安装指南
- asp.net 包含动态创建控件的容器如果要切换显示/隐藏不要用 Visible 属性
- 第二届中国云计算应用论坛圆满落幕
- Dom4j和Xpath(转)
- DLT(DeepLearningTracker)学习与代码理解 (1)
- 多核时代 .NET Framework 4 中的并行编程6---并行LINQ
- Oracle再发力,区块链平台多项更新