简体   繁体   中英

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

I'm trying to create a stored procedure that will update a related row in the BugIt table given an expense report number ErepNo and expense category number EXNo .

The procedure must contain 3 input parameters EXNo , ErepNo and the 'rUpAm' and with one boolean output parameter aRes .

If the ErepStatus is equal to ' Approved ' then the stored value rUpAm is added to BIAct ,the output parameter is set to TRUE and the row is updated.

Else the ErepStatus is equal to ' Denied ' or ' Pending ' an application error is raised and the output parameter is set to FALSE .

Here is what I have tried so far

    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;    
/

Here is my test case to implement the code that I have, which keeps coming up with errors(below)

---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

I think you want:

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;
/

Which, for the sample data:

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;

Then:

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;
/

Outputs Changed and:

SELECT * FROM BugIt;

Gives:

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

And:

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;
/

Outputs Not Changed and the BugIt table has not changed.

db<>fiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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