【问题标题】:Can I delete rows using user defined functions in oracle?我可以在 oracle 中使用用户定义的函数删除行吗?
【发布时间】:2011-05-11 14:18:18
【问题描述】:

我创建了一个用户定义的函数来删除一些数据。它不适用于删除,但适用于选择。我是甲骨文 9i。

函数是这样的:

create or replace function UFN_PURGEDATA(INPUTID IN VarChar2) return number is
  Result number;
begin

  Result := 0;


   DELETE FROM MyTable WHERE MyTable.ID=INPID;

  COMMIT; 

   Result := 1;
 EXCEPTION WHEN OTHERS THEN    

  return(Result);
end UFN_PURGEDATA;

然后我使用select UFN_PURGEDATA('test') from dual 运行它,但得到了结果0

【问题讨论】:

    标签: plsql oracle9i user-defined-functions


    【解决方案1】:

    您的问题的答案是“否”。

    如果您删除错误“处理”,您会发现删除失败,并出现如下异常:

    ORA-14551: 无法执行 DML 查询内的操作

    即您不能在 SELECT 语句中调用的函数中执行插入、更新或删除操作。

    要在 IDE 或 SQL Plus 中执行此函数,请将其包装在更多的 PL/SQL 中,如下所示:

    declare
      l_result number;
    begin
      l_result := my_function(123);
    end;
    

    但是,您需要先在函数中添加 RETURN 语句,否则会失败。

    (注意,我在上面用引号说“处理”是因为它确实是“处理不当”——它以一种非常无益的方式完全掩盖了实际问题。)

    【讨论】:

    • 非常感谢您的回答。那么我该如何执行这个功能呢?我的最终目标是在 java 程序中调用这个函数。
    • -1 此答案中明确的“否”是不正确的。可以使用自主事务(参见 jonearles 的回答)。这种方法存在问题,但仍有可能。
    【解决方案2】:

    如果添加 PRAGMA AUTONOMOUS_TRANSACTION,则可以在 SELECT 中使用的函数内执行 DML。例如:

    create or replace function UFN_PURGEDATA(INPUTID IN VarChar2) return number is
        pragma autonomous_transaction;
    begin
      DELETE FROM MyTable WHERE MyTable.ID=INPUTID;
      COMMIT; 
      return 1;
      EXCEPTION WHEN OTHERS THEN    
      return 0;
    end UFN_PURGEDATA;
    /
    

    但如果可能,您肯定希望避免这种方法。一般来说,如果一个函数在 SELECT 中使用,我们无法知道它会被执行多少次。

    【讨论】:

      【解决方案3】:

      是的,您可以使用 Oracle 中的用户定义函数删除行,但不能从 SELECT 语句中删除。

      您的代码有几个问题:
      - 如果您的函数没有引发异常,则不会返回值
      - 不得在 SELECT 语句中使用执行 DML 的函数;如果你删除你的异常块,你会得到一个 ORA-14551

      【讨论】:

      • 也感谢您的帮助。请告诉我如何达到我的目标。我想从 java 程序中调用这个函数,但也想在 PL/SQL Developer 中测试它。
      • 您应该能够从 Java 调用它,就像使用(匿名)PL/SQL 块的 PL/SQL 一样,使用绑定变量作为返回值 - 请参阅 Tony Andrews 的答案示例.
      【解决方案4】:

      为什么不创建一个带有 OUT 参数返回数字的过程(而不是函数)?如果不使用自治事务技巧,Oracle 不希望您运行具有“副作用”的函数(用于选择)(可以理解为什么我们不希望选择导致 DML 更改)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多