`

如何动态执行存储过程或函数(转)

 
阅读更多
目前在Oracle数据库存储过程研发过程中,遇到需要从某张表中读取存储过程名并进行动态执行的情况,经查找资料,制作成DEMO,并通过测试,现共享下,以备其他同事遇到此种情况时参考。

 

/*动态执行存储过程DEMO*/

DECLARE

 v_Procedure_Name   VARCHAR2(320); --存储过程名

 v_Input_Parameter1 VARCHAR2(320); --传入参数1

 v_Input_Parameter2 VARCHAR2(320); --传入参数2

 v_Return_Int       INTEGER; --接收返回值

 v_Return_String    VARCHAR2(320); --接收返回值 

 v_Sql_Str          VARCHAR2(320); --动态执行SQL语句

BEGIN

 /*获取存储过程名,可以从数据库中动态读取需要执行的存储过程,本DEMO直接赋值*/

 v_Procedure_Name := 'Wms_Application_Out_p.Application_Out_List_Refuse(:i_Str1,:i_Str2,:o_Return_Int,:o_Return_String)';

 /*本DEMO假定需要调用的存储过程有两个传入参数和两个传出参数*/

 v_Input_Parameter1 := 'test01'; --传入参数1,在实际应用中根据具体情况机型赋值

 v_Input_Parameter2 := 'test01'; --传入参数2,在实际应用中根据具体情况机型赋值

 /*动态生成需要执行存储过程的SQL语句*/

 v_Sql_Str := 'BEGIN ' || v_Procedure_Name || '; END;';

 /*执行该SQL语句*/

 EXECUTE IMMEDIATE v_Sql_Str

    USING IN v_Input_Parameter1, IN v_Input_Parameter2, OUT v_Return_Int, OUT v_Return_String; --参数类型和传递顺序必须与存储过程中的保持一致

 /*输出返回值*/

 Dbms_Output.Put_Line(v_Return_Int || v_Return_String);

END;

 

/*动态执行函数DEMO*/

DECLARE

 v_Function_Name    VARCHAR2(320); --函数名

 v_Input_Parameter1 VARCHAR2(320); --传入参数1

 v_Return_String    VARCHAR2(320); --接收返回值 

 v_Sql_Str          VARCHAR2(320); --动态执行SQL语句

BEGIN

 /*获取函数名,可以从数据库中动态读取需要执行的函数,本DEMO直接赋值*/

 v_Function_Name := 'Return_Str_f(:i_Str1)';

 /*本DEMO假定需要调用的函数有1个传入参数*/

 v_Input_Parameter1 := 'test01'; --传入参数1,在实际应用中根据具体情况机型赋值

 /*动态生成需要执行函数的SQL语句*/

 v_Sql_Str := 'begin :v_Return_String := ' || v_Function_Name || '; end;';

 /*执行该SQL语句*/

 EXECUTE IMMEDIATE v_Sql_Str

    USING OUT v_Return_String, IN v_Input_Parameter1; --接收返回值必须在前,传入参数类型和传递顺序必须与函数中保持一致

 /*输出返回值*/

 Dbms_Output.Put_Line(v_Return_String);

END;

 

/*所调用函数*/

CREATE OR REPLACE FUNCTION Return_Str_f(i_Str1 VARCHAR2) RETURN VARCHAR2 IS

 v_Sql_Str VARCHAR2(320);

 v_Str1    VARCHAR2(320);

BEGIN

 /*生成动态执行SQL*/

 v_Sql_Str := 'SELECT ''' || i_Str1 || ''' FROM DUAL';

 EXECUTE IMMEDIATE v_Sql_Str

    INTO v_Str1; --接收返回值

 /*输出返回结果*/

 Dbms_Output.Put_Line('v_str1=' || v_Str1);

 RETURN v_Str1;

END;

 

 

相关资料:

Oracle PL/SQL中动态执行SQL EXECUTE IMMEDIATE

 在plsql中经常遇到sql语句是在过程中动态生成的,这个时候可以用EXECUTE IMMEDIATE来执行生成的sql语句。转一个javaeye(貌似他也是转的,找不到出处)上的EXECUTE IMMEDIATE用法。

    EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析并马上执行动态的SQL语句或非运行时创建的PL/SQL块.动态创建和执行SQL语句性能超前,EXECUTE IMMEDIATE的目标在于减小企业费用并获得较高的性能,较之以前它相当轻易编码.尽管DBMS_SQL仍然可用,
    但是推荐使用EXECUTE IMMEDIATE,因为它获的收益在包之上。
  使用技巧
  1. EXECUTE IMMEDIATE将不会提交一个DML事务执行,应该显式提交
  假如通过EXECUTE IMMEDIATE处理DML命令,那么在完成以前需要显式提交或者作为EXECUTE IMMEDIATE自己的一部分. 假如通过EXECUTE IMMEDIATE处理DDL命令,它提交所有以前改变的数据
  2. 不支持返回多行的查询,这种交互将用临时表来存储记录(参照例子如下)或者用REF cursors.
  3. 当执行SQL语句时,不要用分号,当执行PL/SQL块时,在其尾部用分号.
  4. 在Oracle手册中,未具体覆盖这些功能。下面的例子展示了所有用到Execute immediate的可能方面.希望能给你带来方便.
  5. 对于Forms开发者,当在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功能.
  EXECUTE IMMEDIATE用法例子
  1. 在PL/SQL运行DDL语句
  begin
  execute immediate 'set role all';
  end;
  2. 给动态语句传值(USING 子句)
  declare
  l_depnam varchar2(20) := 'testing';
  l_locvarchar2(10) := 'Dubai';
  begin
  execute immediate 'insert into dept values(:1, :2, :3)'
  using 50, l_depnam, l_loc;
  commit;
  end;
  3. 从动态语句检索值(INTO子句)
  declare
  l_cntvarchar2(20);
  begin
  execute immediate 'select count(1) from emp'
  into l_cnt;
  dbms_output.put_line(l_cnt);
  end;
  4. 动态调用例程.例程中用到的绑定变量参数必须指定参数类型.黓认为IN类型,其它类型必须显式指定
  declare
  l_routin varchar2(100) := 'gen2161.get_rowcnt';
  l_tblnam varchar2(20) := 'emp';
  l_cntnumber;
  l_status varchar2(200);
  begin
  execute immediate 'begin ' l_routin '(:2, :3, :4); end;'
  using in l_tblnam, out l_cnt, in out l_status;
  if l_status != 'OK' then
  dbms_output.put_line('error');
  end if;
  end;
  5. 将返回值传递到PL/SQL记录类型;同样也可用%rowtype变量
  declare
  type empdtlrec is record (empnonumber(4),
  enamevarchar2(20),
  deptnonumber(2));
  empdtl empdtlrec;
  begin
  execute immediate 'select empno, ename, deptno ' 
  'from emp where empno = 7934'
  into empdtl;
  end;
  6. 传递并检索值.INTO子句用在USING子句前
  declare
  l_deptpls_integer := 20;
  l_nam varchar2(20);
  l_loc varchar2(20);
  begin
  execute immediate 'select dname, loc from dept where deptno = :1'
  into l_nam, l_loc
  using l_dept ;
  end;
  7. 多行查询选项.对此选项用insert语句填充临时表,用临时表进行进一步的处理,也可以用REF cursors纠正此缺憾.
  declare
  l_sal pls_integer := 2000;
  begin
  execute immediate 'insert into temp(empno, ename) ' 
  'select empno, ename from emp ' 
  'wheresal :1'
  using l_sal;
  commit;
  end;
  对于处理动态语句,EXECUTE IMMEDIATE比以前可能用到的更轻易并且更高效.当意图执行动态语句时,适当地处理异常更加重要.应该关注于捕捉所有可能的异常.

 

分享到:
评论

相关推荐

    java调用oracle存储过程或者函数

    4. 执行存储过程:调用`CallableStatement.execute()`方法执行存储过程。 5. 获取结果:如果是查询操作,可以使用`ResultSet`处理结果;如果是非查询操作,可以通过`CallableStatement`的`getXXX()`方法获取输出参数...

    MySQL实验报告5(存储过程与函数)(1)(1).pdf

    定义完存储过程后,使用“delimiter”关键字更改语句结束符,以便能够正确地定义存储过程或函数中的多条语句。 2. 创建函数 函数与存储过程类似,也是一种子程序。不同之处在于函数必须返回一个值。报告中并没有...

    存储过程与函数的区别

    执行存储过程时,数据库会根据已经编译好的计划执行,而不需要每次运行时都重新解析SQL。 相比之下,函数(Function)更像是一个计算单元,它接收输入参数并返回一个单一的值。函数必须有返回值,而且这个返回值的...

    原创sql存储过程函数范例

    原创sql存储过程函数范例,一是为了自己方便查找,今天到公司因为没有我保存的一些范例,一个简单的例子写了半个小时,如果有范例直接套几分钟肯定搞定,所以索性上传到CSDN上,何时何地都能找到我的范例了。...

    Oracle存储过程、函数和包

    - **复用性**:存储过程和函数可以被多个应用程序或存储过程调用,从而提高代码的复用性和维护性。 #### 2. 存储过程的优点 - **远程访问**:由于存储过程驻留在数据库服务器上,因此可以从任何客户端进行访问。 - ...

    第11章MySQL存储过程与函数.docx

    4. 存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用。 创建存储过程的示例: CREATE PROCEDURE getnamebysno(in xh char(10), out name char(20)) BEGIN SELECT sname INTO ...

    存储过程和函数的区别

    3. **无返回值**:与函数不同,存储过程不直接返回一个具体的值,而是通过输出参数或直接修改数据库状态来实现其功能。 4. **支持多条SQL语句**:存储过程中可以包含多条SQL语句,这些语句可以是查询、更新或其他...

    常用SQL工具存储过程与函数.rar

    1. **性能提升**:由于存储过程在首次执行时会被编译成服务器内部的执行计划,后续调用只需传入参数即可,减少了网络传输和解析的时间。 2. **安全增强**:可以通过权限控制来限制对存储过程的访问,而不是直接对...

    Mysql存储过程和函数

    - **递归调用**:存储过程和函数中可以递归地调用其他的过程或函数。 #### 六、存储过程与函数的维护 1. **删除存储过程/函数**: ```sql DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name ``` 2. **查看...

    存储过程和函数

    根据提供的文件信息,本文将详细解析数据库中的存储过程与函数,并深入探讨自主事务(autonomous_transaction)的概念及其在PL/SQL中的应用。 ### 一、存储过程 #### 1. 创建存储过程 存储过程是一种存储在数据库...

    第8章 存储过程、函数和包.ppt

    1. **安全性**:只有获得授权的用户才能执行存储过程或函数,这通过数据库提供的权限管理机制实现。 2. **重用性**:存储过程和函数的信息存储在数据字典中,可以作为公共模块被多次调用,减少了代码重复。 3. **...

    sqlserver 存储过程 函数 常用知识点

    - **定义**:存储过程是一组预编译的SQL语句,可以接受参数,执行特定任务,如数据查询、更新或插入等。 - **优点**:提高性能(因为编译只需一次),增强安全性(可以通过权限控制访问),减少网络流量(一次调用...

    Oracle存储过程和函数(最详细包含emp 表实例操作,边看边操作)

    在Oracle数据库中,存储过程和函数是重要的编程元素,用于执行复杂的数据库操作和业务逻辑。本篇文章将深入探讨这两个概念,并结合经典的SCOTT库中的EMP表进行实例操作。 **一、Oracle存储过程** 存储过程是一组预...

    GBase 8S 自定义存储过程和函数.doc

    如果需要删除已创建的存储过程或函数,使用`DROP PROCEDURE/FUNCTION`语句: ```sql DROP PROCEDURE/FUNCTION <存储过程名> (参数列表); ``` 总的来说,GBase 8S 的自定义存储过程和函数功能使得数据库开发者可以...

    sql动态行转列 存储过程

    在本案例中,我们主要探讨如何使用SQL语句,尤其是存储过程,来实现动态的行转列功能。这在处理具有多个分类或时间序列的数据时特别有用,可以更直观地展示数据。 首先,我们需要创建一个存储过程来执行这个操作。...

    java中调用oracle的存储过程和函数

    3. **CallableStatement**:是`PreparedStatement`的子接口,用于执行存储过程或函数。 #### 二、环境搭建 为了能够在Java中调用Oracle数据库中的存储过程和函数,首先需要确保以下条件得到满足: 1. **JDBC驱动*...

    Oracle定时执行存储过程

    Oracle 定时执行存储过程 oracle 是一个功能强大的关系型数据库管理系统,可以执行各种复杂的任务,其中包括定时执行存储过程。定时执行存储过程可以让 oracle 自动执行某些操作,而不需要人工干预。下面我们将详细...

    Mysql手册20-存储过程和函数

    - CALL 语句用于执行存储过程。 - BEGIN ... END 语句用于定义一个复合语句块,这在存储程序的主体中非常常见。 - DECLARE 语句用于在存储程序中声明变量。 - 存储程序中的变量用于存储临时数据。 - 条件和处理程序...

    存储过程中怎么动态执行sql语句

    “存储过程中怎么动态执行SQL语句”这一标题表明文章将介绍如何在Oracle数据库的存储过程中编写能够动态执行的SQL语句。动态SQL是指在运行时才能确定其具体内容的SQL语句,它允许用户根据不同的条件构造不同的查询或...

    存储过程 函数

    这些工具提供了图形化界面,便于创建、修改和执行存储过程及函数,简化了数据库开发和维护工作。 在我们的例子中,`省市区数据.sql`这个文件名可能表示一个包含省市区数据的SQL脚本,通常用于初始化数据库或者更新...

Global site tag (gtag.js) - Google Analytics