【问题标题】:oracle procedure returns integeroracle 过程返回整数
【发布时间】:2008-11-04 16:21:54
【问题描述】:

在 oracle 中,我想创建一个删除存储过程,它根据删除的结果返回一个整数。

这是我目前所拥有的。

create or replace
PROCEDURE Testing
( 
iKey IN VARCHAR2
)
 AS 

BEGIN
  delete from MyTable WHERE 
  TheKey = iKey;

END Testing;

我已尝试将 RETURNS INTEGER 放入,但存储过程无法编译。

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    过程不返回值。一个函数返回一个值,但你不应该在函数中执行 DML(否则你不能做一些事情,比如在 SQL 语句中引用函数,你会混淆权限授予,因为通常 DBA 希望能够授予只读用户访问权限到所有功能,以便用户始终如一地进行计算等)。

    您可以在过程中添加 OUT 参数以返回状态。如果“成功”表示更新了一行或多行,则可以使用 SQL%ROWCOUNT 获取先前 SQL 语句修改的行数的计数,并使用它来填充返回参数,即

    CREATE OR REPLACE PROCEDURE test_proc (
      p_iKey    IN VARCHAR2,
      p_retVal OUT INTEGER
    )
    AS
    BEGIN
      DELETE FROM myTable
       WHERE theKey = p_iKey;
    
      IF( SQL%ROWCOUNT >= 1 )
      THEN
        p_retVal := 1;
      ELSE
        p_retVal := 0;
      END IF;
    END test_proc;
    

    当然,从一般代码清晰度的角度来看,我对似乎试图返回状态代码的 OUT 参数持怀疑态度。假设成功并在发生错误时抛出异常通常会更好地为您服务。

    【讨论】:

      【解决方案2】:

      您可以使用存储过程来返回结果。

      CREATE OR REPLACE PROCEDURE testing (iKey IN VARCHAR2, oRes OUT NUMBER)
      AS
      BEGIN
         DELETE FROM MyTable
               WHERE TheKey = iKey;
      
         oRes := SQL%ROWCOUNT;
      END;
      

      要调用该过程,请使用以下内容:

      DECLARE
         pRes   NUMBER;
      BEGIN
         testing ('myspecialkey', pRes);
         DBMS_OUTPUT.put_line (pRes);
      END;
      

      【讨论】:

        【解决方案3】:

        使用函数和隐式 SQL 游标确定删除的行数

        create or replace
        FUNCTION Testing
        ( 
        iKey IN VARCHAR2
        ) RETURN INTEGER
         AS 
        
        BEGIN
          delete from MyTable WHERE 
          TheKey = iKey;
        
          RETURN SQL%ROWCOUNT;
        
        END Testing;
        

        应该可以的

        【讨论】:

        • ORA-14551:无法在查询中执行 DML 操作
        • @Benoit 应该是这样,该函数旨在从 PL/SQL 而非普通 SQL 调用
        【解决方案4】:

        您可能正在寻找一个函数。

        FUNCTION TESTING (iKEY IN VARCHAR2) RETURN NUMBER
        IS
          v_count NUMBER;
          yourNumber NUMBER;
        BEGIN
        
          SELECT COUNT(*) INTO v_count
          FROM MyTable
          WHERE TheKey = iKey;
        
          IF v_count > 0
            THEN
               DELETE FROM MyTable 
               WHERE TheKey = iKey;
        
               SELECT COUNT(*) INTO v_count
               FROM MyTable
               WHERE TheKey = iKey;
        
               IF (v_count = 0)
                 THEN
                   yourNumber :=  1; --means successful deletion
               END IF;
          ELSE
               yourNumber := 0; --means no items to delete
          END IF;
          return yourNumber;
        
          EXCEPTION
              WHEN OTHERS THEN
                RETURN -1; --means error was encountered
        END TESTING;
        

        注意:在我工作的地方,我们通常将函数放在 sql 包中。

        【讨论】:

        • 2选加删除?请改用 stjohnrow 建议的 SQL%ROWCOUNT 方法。
        • 这很酷。不知道那件事。那肯定更好。
        【解决方案5】:

        SQL%ROWCOUNT 只会在 DML 之后立即返回一个值,如果执行另一个 DML,它的值将重置。

        为了解决我在循环中执行删除的问题,我在 dml 之后发出了以下命令:

        row_count := row_count + SQL%ROWCOUNT;
        

        请确保您声明并初始化row_count := 0;

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-03
          • 2016-08-19
          • 1970-01-01
          相关资源
          最近更新 更多