PL/SQL-->动态SQL调用包中函数或过程
PL/SQL-->动态SQL调用包中函数或过程动态SQL主要是用于针对不同的条件或查询任务来生成不同的SQL语句。最常用的方法是直接使用EXECUTE IMMEDIATE来执行动态SQL语句字符串或字符串变量。但是对于系统自定义的包或用户自定的包其下的函数或过程,不能等同于DDL以及DML的调用,其方式稍有差异。1、动态SQL调用包中过程不正确的调用方法[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);78 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 statementORA-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);78 -- 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调用包中过程正确的调用方法[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);78 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调用包中过程带变量的情形[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);78 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 contextORA-06550: line 1, column 7:PL/SQL: Statement ignoredORA-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);78 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中调用包中函数的情形[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;';56 --DBMS_OUTPUT.put_line (v_sql);78 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'方式来拼接动态sqlc、可以拼接sql到变量,也可以直接将动态sql紧跟在EXECUTE IMMEDIATE,个人上一个:DataGuard环境搭建
下一个:Oracle索引扫描的4种类型
- 更多SQLServer疑问解答:
- 配置MSSQL复制指定快照文件夹提示:不是有效的路径或文件名
- 详细解读varchar和Nvarchar区别
- SQL SERVER 2005 同步复制技术
- 进程未能大容量复制到表 解决方法
- MSSql实例教程:MSSql数据库同步
- SQLServer2000同步复制技术实现(分发和订阅)
- sqlserver
- SQLSERVER
- 测试 sqlserver 最大用户数连接
- 写出一条Sql语句:取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的
- sqlserver2008的安装问题。
- 为什么安装的SQL server 2008我的没有MSSQLSERVER协议啊?
- 怎样把exel表里的数据复制到sqlserver表里
- sqlserver数据库主键和外键问题
- sqlserver 中的左表连接查询和右表连接查询有啥不同?有什么用?