【问题标题】:Oracle: Call a function from "select from dual" do nothingOracle:从“从双重选择”中调用一个函数什么都不做
【发布时间】:2018-03-16 00:43:03
【问题描述】:

我有一个插入和更新表的函数。从以下位置调用它:

select AGENTS_REGISTRATION() from dual;

或:

declare
  x NUMBER;
begin
  select AGENTS_REGISTRATION() into x from dual;
end;
/

什么都不做。另一种形式进行了必要的更改:

declare
  x NUMBER;
begin
  x := AGENTS_REGISTRATION();
end;
/

前两个表达式有什么问题?

【问题讨论】:

  • “什么都不做”是什么意思?由于查询中不允许使用 DML,因此您应该得到 ORA-14551 错误。
  • 我在 Oracle SQL Developer 中执行表达式,但没有得到 ORA-14551。我看到人们写了 You can't use a function that modifying data in a select statement。您可以添加您的评论作为答案吗?不知道……
  • 不允许在函数内部执行 DML 操作。如果正如您所说的“它什么都不做”,那么可能存在 when others then null 或其他类型的异常处理构造来抑制 ORA-14551 错误。
  • @NicholasKrasnov 你是对的,它有:EXCEPTION WHEN OTHERS THEN 并且 EXCEPTION 块内的错误报告也尝试写入 DB,所以我没有任何问题的迹象((
  • 这就是为什么您永远不应该使用 WHEN OTHERS... 除非您确切知道自己在做什么以及后果是什么。

标签: oracle function plsql


【解决方案1】:

Oracle 不允许在查询中进行DML 操作。查询中inserts/updates/deletes 数据将引发的调用函数:

ORA-14551:无法在查询中执行 DML 操作

如果exception 被困在函数内部,查询将不会引发错误 - 使用WHEN OTHERS 异常处理程序(或直接使用pragma exception_init 捕获ORA-14551)而不重新引发错误是非常危险的,因为您在这个例子中看到过。

虽然我不推荐这样做,但如果函数定义为 autonomous transaction(通过使用 pragma autonomous_transaction),则可以在查询中使用 DML 操作 - 但这会导致更多问题。

解决方案是不要在查询中调用函数 - 这样做当然没有意义。

【讨论】:

    【解决方案2】:

    查看http://www.dba-oracle.com/t_ora_14551_cannot_perform_a_dml_operation_inside_a_query.htm

    create or replace function myFunction return varchar2 as
    begin
    update emp set empno = empno +1 where empno = 0;
    return 'Yeah';
    end; 
    /
    
    
    SQL> var myVar VARCHAR2
    SQL> call myFunction() INTO :myVar;
    SQL> print myVar 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      • 2013-12-25
      • 2019-02-08
      • 1970-01-01
      • 2017-04-27
      • 1970-01-01
      相关资源
      最近更新 更多