存储过程(菜鸟程序员),我的代码有什么问题?
Stored Procedure (rookie programmer), What's wrong with my code?
我正在尝试创建一个存储过程,它将更新 BugIt
table 中的相关行,给定支出报告编号 ErepNo
和支出类别编号 EXNo
.
该过程必须包含 3 个输入参数 EXNo
、ErepNo
和 '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;
给出:
EXNO | BIACT
---: | ----:
1 | 2
2 | 2
3 | 3
并且:
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 Changed
并且 BugIt
table 没有改变。
db<>fiddle here
我正在尝试创建一个存储过程,它将更新 BugIt
table 中的相关行,给定支出报告编号 ErepNo
和支出类别编号 EXNo
.
该过程必须包含 3 个输入参数 EXNo
、ErepNo
和 '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;
给出:
EXNO | BIACT ---: | ----: 1 | 2 2 | 2 3 | 3
并且:
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 Changed
并且 BugIt
table 没有改变。
db<>fiddle here