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> DECLARE
2 v_sql VARCHAR2 (300);
3 v_tab VARCHAR2 (30) := 'DEPT';
4 BEGIN
5 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> DECLARE
2 v_sql VARCHAR2 (300);
3 v_tab VARCHAR2 (30) := 'DEPT';
4 BEGIN
5 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> DECLARE
2 v_sql VARCHAR2 (300);
3 v_tab VARCHAR2 (30) := 'DEPT';
4 BEGIN
5 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> DECLARE
2 v_sql VARCHAR2 (300);
3 v_tab VARCHAR2 (30) := 'DEPT';
4 BEGIN
5 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> DECLARE
2 v_sql VARCHAR2 (300);
3 v_tab VARCHAR2 (30) := 'DEPT';
4 BEGIN
5 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/leshami scott@USBO> DECLARE
2 v_sql VARCHAR2 (300);
3 BEGIN
4 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 test PL/SQL procedure successfully completed. --直接使用下面的方式可以实现
scott@USBO> BEGIN
2 EXECUTE IMMEDIATE 'begin dbms_output.put_line(''This is only a test''); end;';
3 END;
4 /
This is only a test PL/SQL procedure successfully completed.
5、小结
a、对于动态SQL来调用函数,我们需要使用begin .. end来封装块,而不是简单的类似于DML以及DDL的调用方法
b、不能使用'exec pkg_name.proc_name'方式来拼接动态sql
c、可以拼接sql到变量,也可以直接将动态sql紧跟在EXECUTE IMMEDIATE,个人更倾向于使用前者
更多参考
PL/SQL 联合数组与嵌套表
PL/SQL 变长数组
PL/SQL --> PL/SQL记录
dbms_xplan之display_cursor函数的使用
PL/SQL --> 动态SQL调用包中函数或过程的更多相关文章
- oracle 包,函数,过程,块的创建和执行及在java中执行(转)
SQL> create or replace procedure sp_guocheng1 is--如果有这个名字就替换 2 begin--执行部分 3 insert into guoc ...
- 使用命令动态更新JAR包中的文件
动态更新JAR包中的文件,经本人实际测试可正常执行! 一.查询jar包中要替换的文件位置 jar -tvf gateway.jar | grep topjui.config.js 二.在当前 ...
- [SQL]动态sql语句基本语法
动态sql语句基本语法 :普通SQL语句可以用Exec执行 eg: Select * from tableName Exec('select * from tableName') Exec sp_ex ...
- mybatis Dynamic SQL动态 SQL
动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格 ...
- DLL模块例1:使用.def模块导出函数,规范修饰名称,显示连接调用dll中函数
以下内容,我看了多篇文章,整合在一起,写的一个例子,关于dll工程的创建,请参考博客里另一篇文章:http://www.cnblogs.com/pingge/articles/3153571.html ...
- <asp:Button点击查询后,调用js中函数展现加载圈
<div> <div id='paneloading' style='display:none;position:fixed;top:0px;left:0px;z-index:999 ...
- R语言学习笔记(二十):stringr包中函数介绍(表格)
stringr包中的重要函数 函数 功能说明 R Base中对应函数 使用正则表达式的函数 str_extract() 提取首个匹配模式的字符 regmatches() str_extract_all ...
- DELPHI中函数、过程变量的声明与应用
Procedure型变量: 在DELPHI中,函数.过程的地址可以赋给一个特殊类型的变量,变量可用如下方式声明: var p : procedure(num:integer); //过程 或: var ...
- PL/SQL 动态SQL
declare msql varchar2(200); row_id varchar2(200); begin loop row_id := 'AAATGiAAEAAAuLLAAA'; msql := ...
随机推荐
- UDP数据接收服务器
简介 这是我在做一个要用UDP方式进行数据传输时,自己写的一个多线程的UDP数据接收服务器, 它能将接收到的UDP数据包存成文件,并提供数据包接收时间监测: 还支持键盘命令响应,以将数据写到新的文件, ...
- UML--核心视图之用例图
如果说UML是一门语言,那么元素就是UML的基本词汇,视图就是语法. UML通过视图将基本元素组织在一起,形成有意义的句子. 静态视图,顾名思义,就是表达静态事物的.包括用例图.类图和包图. 用例图 ...
- 【转】 树莓派学习笔记——I2C设备载入和速率设置
原文网址:http://blog.csdn.net/xukai871105/article/details/18234075 1.载入设备 方法1——临时载入设备 sudo modprobe -r i ...
- Google的Protocol Buffer格式分析
[转]转自:序列化笔记之一:Google的Protocol Buffer格式分析 从公开介绍来看,ProtocolBuffer(PB)是google 的一种数据交换的格式,它独立于语言,独立于平台.作 ...
- 简述tcp协议对http性能的影响及优化
当网站服务器并发连接达到一定程度时,你可能需要考虑服务器系统中tcp协议设置对http服务器的影响. tcp相关延时主要包括: 1.tcp连接时建立握手: 2.tcp慢启动拥塞控制: 3.数据聚集的N ...
- deciaml(十进制浮点运算)
# -*- coding: utf-8 -*- # ==================== #File: python #Author: python #Date: 2014 #========== ...
- Java客户端Jedis的八种调用方式
redis是一个著名的key-value存储系统,而作为其官方推荐的java版客户端jedis也非常强大和稳定,支持事务.管道及有jedis自身实现的分布式. 在这里对jedis关于事务.管道和分 ...
- Zookeeper学习记录(一):设计与实现
概述 Zookeeper是一个分布式的.开源的分布式应用协调服务.它暴露了一组简单的基础原件,分布式应用可以在这些原件之上实现更高级别的服务,如同步.配置维护.群组.和命名.它被设计成容易编程实现的, ...
- 【软件技巧】Sublime Text为不同语法定义不同高亮
Sublime Text默认的语法高亮已经非常美丽了,可是对于个别语言还是有些不爽. 默认高亮规则叫Monokai,能够从Preferences->Settings - Default中看到: ...
- Linux入门基础 #8:Linux拓展权限
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...