在Oracle数据库的自定义函数中调用存储过程

日期: 2012-08-07 作者:Brian Peasland翻译:孙瑞 来源:TechTarget中国 英文

问:关于Oracle数据库,我有以下几个问题想请教:   1、请问为何我们不能再自定义函数中调用一个存储过程呢?   2、请问能不能再触发器内部创建一个表?   答:当然可以在自定义函数中调用存储过程,请参考以下例子: 以下是引用片段:SQL> create table test_tab (tab_id number); Table created. SQL> insert into test_tab values (10); 1 row created……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

问:关于Oracle数据库,我有以下几个问题想请教:

  1、请问为何我们不能再自定义函数中调用一个存储过程呢?

  2、请问能不能再触发器内部创建一个表?

  答:当然可以在自定义函数中调用存储过程,请参考以下例子:

以下是引用片段:
SQL> create table test_tab (tab_id number);
Table created.
SQL> insert into test_tab values (10);
1 row created.
SQL>  insert into test_tab values (20);
1 row created.
SQL> commit;
SQL> create table test_tab_audit (tab_id number, aud_date date);
Table created.
SQL> create or replace procedure test_proc (id number)
  2  as
  3  begin
  4     null;
  5  end;
  6  /
Procedure created.
SQL> create or replace function test_fn(v_id number)
  2  return number
  3  as
  4  begin
  5     test_proc(v_id);
  6     return v_id+1;
  7  end;
  8  /
Function created.
SQL> select tab_id,test_fn(tab_id) from test_tab;
    TAB_ID TEST_FN(TAB_ID)
---------- ---------------
        10              11
        20              21

    当函数从SELECT语句调用的时候,你用存储过程能做的就非常有限。你不能在查询中使用DML或者DDL,否则可能会抛出以下的错误:

  • ORA-14551: cannot perform a DML operation inside a query
  • ORA-14552: cannot perform a DDL, commit or rollback inside a query or DML

  但是下面的例子中,调用存储过程就不会出现问题:

SQL> create or replace procedure test_proc (id number)
  2  as
  3  begin
  4     insert into test_tab_audit values (id,sysdate);
  5     commit;
  6  end;
  7  /
Procedure created.
SQL> declare
  2     val number;
  3  begin
  4     val:=test_fn(10);
  5  end;
  6  /
PL/SQL procedure successfully completed.
SQL> select * from test_tab_audit;
    TAB_ID AUD_DATE
---------- ---------
        10 30-JUL-12

  而针对你的第二个关于触发器的问题,答案是肯定的,你可以创建表。使用EXECUTE IMMEDIATE命令即可。

  SQL> CREATE TRIGGER test_tab_trigger
  2 BEFORE INSERT ON test_tab
  3 FOR EACH ROW
  4 BEGIN
  5 EXECUTE IMMEDIATE 'create table another table (id number)';
  6 END;
  7 /
  Trigger created.

  然而真正你需要了解的问题应该是:该不该在触发器中创建一个表?通常来说,动态创建一个表是不提倡的,应用系统的表应该预先创建。此外,每一个INSERT、UPDATE或者DELETE启动触发器的时候,都会消耗很长的时间,因为你需要等待DML命令完成之前的表创建完毕。所以我们认为在触发器中写这些代码是不合适的。

作者

Brian Peasland
Brian Peasland

Techtarget旗下Searchoracle网站的资深专家,有16年IT行业经验、计算机科学硕士、专攻数据库方向,曾担任系统管理员等职。此外,他还获Oracle 7.3、8和8i的OCP数据库管理员证书,目前为SGT Inc.公司首席DBA。

翻译

孙瑞
孙瑞

相关推荐