繁体   English   中英

存储过程(菜鸟程序员),我的代码有什么问题?

[英]Stored Procedure (rookie programmer), What's wrong with my code?

我正在尝试创建一个存储过程,该过程将在给定费用报告编号ErepNo和费用类别编号EXNo更新BugIt表中的相关行。

该过程必须包含 3 个输入参数EXNoErepNo'rUpAm'以及一个布尔输出参数aRes

如果ErepStatus等于“ Approved ”,则将存储的值rUpAm添加到BIAct ,输出参数设置为TRUE并更新行。

否则ErepStatus等于 ' Denied ' 或 ' Pending ' 引发应用程序错误并且输出参数设置为FALSE

这是我迄今为止尝试过的

    CREATE OR REPLACE PROCEDURE StoredProcedure1
(tEXNo IN BugIt.EXNo%TYPE,
 tErepNo IN ER.ErepNo%TYPE,
 rUpAm IN INTEGER, 
 aRes OUT BOOLEAN ) IS
FOUND BOOLEAN := False; 
tErepStatus ER.ErepStatus%TYPE;
tBIAct BugIt.BIAct%TYPE;


CURSOR ERCur(TmpErepNo ExpI.ErepNo%TYPE)is
 SELECT ExpI.EXNo, ER.ErepStatus
    FROM ER, BugIt, ExpI
    WHERE ER.ErepNo = tErepNo
      AND BugIt.EXNo = ExpI.EXNo
      AND ER.ErepNo = ExpI.ErepNo
    ORDER BY ErepStatus DESC;
    
BEGIN 
OPEN ERCur(tErepNo);
LOOP
    FETCH ERCur INTO  tErepStatus, tBIAct;
    EXIT WHEN ERCur%NOTFOUND;
    IF tErepStatus = 'APPROVED' THEN
        FOUND := TRUE;
    END IF;
    IF tErepStatus = 'PENDING' OR tErepStatus = 'DENIED' THEN
        FOUND := False;
        EXIT;
    END IF;
END LOOP;

CLOSE ERCur;
IF FOUND THEN
    tBIAct := tBIAct + rUpAm;
    aRes := TRUE;
    UPDATE BugIt 
    Set BIAct = tBIAct
    WHere EXNo = tEXNo;
          
ElSE 
    tBIAct := tBIAct;
    aRes := False;
END IF;
    
    
    
    
EXCEPTION
WHEN OTHERS THEN aRes := False;
  raise_application_error(-20001, 'Database error');
END;    
/

这是我的测试用例来实现我拥有的代码,它不断出现错误(如下)

---test--
SET Serveroutput on;

SELECT ExpI.EXNo, ER.ErepStatus
    FROM ER, BugIt, ExpI
    WHERE ER.ErepNo = 21
      AND BugIt.EXNo = ExpI.EXNo
      AND BugIt.ErepNo = ExpI.ErepNo
    ORDER BY ErepStatus DESC;
    
-- Test script
DECLARE
Result BOOLEAN;
aBIAct BugIt.BIAct%TYPE;
BEGIN

StoredProcedure1(2, 2, 3, Result);
IF Result then
    dbms_output.put_line('updated element to the BugIt table');
ELSE
    dbms_output.put_line('Row not updated to the  BugIt table');
END IF;
END;
/


ERROR at line 1:
ORA-20001: Database error
ORA-06512: at "SYSTEM.SPROLLUPEXPITEM", line 51
ORA-06512: at line 6

我想你想要:

CREATE OR REPLACE PROCEDURE StoredProcedure1 (
  tEXNo IN BugIt.EXNo%TYPE,
  tErepNo IN ER.ErepNo%TYPE,
  rUpAm IN INTEGER, 
  aRes OUT BOOLEAN
)
IS
  tErepStatus ER.ErepStatus%TYPE;
BEGIN
  SELECT ER.ErepStatus
  INTO   tErepStatus
  FROM   ER
         INNER JOIN ExpI
         ON ( ER.ErepNo = ExpI.ErepNo )
         INNER JOIN BugIt
         ON ( BugIt.EXNo = ExpI.EXNo )
  WHERE  ER.ErepNo = tErepNo
  AND    ER.ErepStatus IN ( 'APPROVED', 'PENDING', 'DENIED' )
  ORDER BY ErepStatus DESC
  FETCH FIRST ROW ONLY;
  
  aRes := tErepStatus = 'APPROVED';
  
  IF aRes THEN
    UPDATE BugIt 
    SET   BIAct = BIAct + rUpAm
    WHERE EXNo = tEXNo;
  END IF;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    aRes := FALSE;
END;
/

其中,对于样本数据:

CREATE TABLE ER ( ErepNo, Erepstatus ) AS
SELECT 1, 'APPROVED' FROM DUAL UNION ALL
SELECT 2, 'PENDING'  FROM DUAL UNION ALL
SELECT 3, 'DENIED'   FROM DUAL UNION ALL
SELECT 3, 'APPROVED' FROM DUAL;

CREATE TABLE ExpI ( ErepNo, EXNo ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL UNION ALL
SELECT 3, 3 FROM DUAL;

CREATE TABLE BugIt ( EXNo, BIAct ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL UNION ALL
SELECT 3, 3 FROM DUAL;

然后:

DECLARE
  aRes BOOLEAN;
BEGIN
  StoredProcedure1( 1, 1, 1, aRes );
  IF ares THEN
    DBMS_OUTPUT.PUT_LINE( 'Changed' );
  ELSE
    DBMS_OUTPUT.PUT_LINE( 'Not Changed' );
  END IF;
END;
/

输出Changed并且:

SELECT * FROM BugIt;

给出:

\n EXNO |  BIACT\n ---: |  ----:\n    1 |  2\n    2 |  2\n    3 |  3\n

和:

DECLARE
  aRes BOOLEAN;
BEGIN
  StoredProcedure1( 3, 3, 1, aRes );
  IF ares THEN
    DBMS_OUTPUT.PUT_LINE( 'Changed' );
  ELSE
    DBMS_OUTPUT.PUT_LINE( 'Not Changed' );
  END IF;
END;
/

输出Not ChangedBugIt表未更改。

db<> 在这里摆弄

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM