事务上下文中Oracle存储过程/函数的语义

Luk*_*der 2 oracle stored-procedures transactions batch-file

我最近收到了一位同事关于提交存储功能的一些意见.我们是否使用过程或函数在Oracle数据库中执行脱机/批处理逻辑主要是我们的应用程序的品味问题.在这两种情况下,我们都返回代码作为函数结果或作为过程OUT参数.我们通常要求从PL/SQL调用那些脱机/批处理例程,而不是从SQL调用:

-- good
declare
  rc number(7);
begin
  rc := our_function(1, 2, 3);
end;

-- less good
select our_function(1, 2, 3) from dual;
Run Code Online (Sandbox Code Playgroud)

后者不太好的原因是因为our_function出于性能原因可能会提交事务.这对于批处理例程是可以的.

问题是:是否有围绕此主题的最佳实践,或某些特殊关键字阻止在编译器级别的SQL语句中使用此类函数?或者我们应该避免批处理操作的功能而只使用程序?

Gar*_*ers 6

您可以使用RESTRICT_REFERENCES指示函数不会读/写包或数据库状态.

CREATE PACKAGE t_pkg AS
   FUNCTION showup (msg VARCHAR2) RETURN VARCHAR2;
   PRAGMA RESTRICT_REFERENCES(showup, WNDS, RNDS);
END t_pkg;
/
-- create the package body
CREATE OR REPLACE PACKAGE BODY t_pkg AS
   FUNCTION showup (msg VARCHAR2) RETURN VARCHAR2 IS
    v_val varchar2(1);
   BEGIN
      select dummy into v_val from dual;
      RETURN v_val;
   END;
END t_pkg;
/
Run Code Online (Sandbox Code Playgroud)

曾经是这样的情况,SQL不允许你调用函数,除非它做出了这样的承诺,但是这个限制被删除了.

我宁愿把它作为程序和功能之间的区别.值得注意的是,如果PL/SQL函数引发NO_DATA_FOUND异常,则调用SQL语句不会失败(因为找不到数据不是SQL错误).所以我更喜欢使用过程,除非该对象专门设计为从SQL调用.