我试图编写一个存储过程,它接受一个ID的输入,然后使用不同的标准搜索该项目的3个不同的表。我的一个解决方案是逐个执行每个表上的select语句,如果NO_DATA_FOUND
没有找到任何内容,则捕获select
异常。
在伪代码中:
Select item from from first table
If no data found, throw exception.
Handle exception by selecting data from second table
If no data found, throw another exception.
Handle exception by selecting data from third table (if the data is not present in any row it should return 0 rows)
以下是我所拥有的:
OPEN REQUEST FOR
SELECT REQ_TYPE, REQ_TYPE_STATUS FROM TABLEONE
WHERE TABLEONE.REQ_ID = REQUESTID
AND (REQ_STATUS = 'D' OR REQ_STATUS = 'A');
EXCEPTION WHEN NO_DATA_FOUND THEN
BEGIN
OPEN REQUEST FOR
SELECT REQ_TYPE, '-' AS REQ_TYPE_STATUS FROM TABLETWO
WHERE TABLETWO.REQ_ID = REQUESTID;
EXCEPTION WHEN NO_DATA_FOUND THEN
begin
OPEN REQUEST FOR
SELECT REQ_TYPE, '-' as REQ_TYPE_STATUS FROM THIRDTABLE
WHERE THIRDTABLE.REQ_ID = REQUESTID;
end;
END;
如果在TABLEONE中找到一个项目,它会成功返回该数据。但是,在捕获的异常内执行的SELECT
操作似乎不会运行,因为存储过程不会返回任何行。
我已经单独验证了我正在搜索的数据肯定存在于TABLETWO和/或TABLETHREE中。
语法在编译时有效,只是如果项目不存在于TABLEONE中(但存在于TABLETWO或TABLETHREE中),它不会返回任何行。
有什么想法吗?
答案 0 :(得分:0)
归功于@Franek。
引用的linked article解释了以下内容:
光标FOR循环很聪明。它不会像现在这样引发NO-DATA-FOUND;如果 没有任何东西可以获取,它将退出循环并终止 执行成功。因此,如果您打算将其作为一个处理 例外 - 你不能。
我试图做的事情显然是不可能的。因此,我用这种方式实现了它:
<强>伪代码:强>
Search for the item in the first table
If item was found
select the details of it from the first table
If item was not found
search for the item in the second table
If Item was found
Select the details of it from the second table
If item was not found
Select the item from the third table (returning blank if it's not found here neither)
PL / SQL实施:
-- Search for the request ID in the first table
SELECT COUNT(REQ_ID) INTO requestFound FROM FIRSTTABLE
WHERE FIRSTTABLE.REQ_ID = REQUESTID
AND (REQ_STATUS = 'D' OR REQ_STATUS = 'A');
IF(REQUESTFOUND > 0) THEN
-- Select the request details
OPEN REQUEST FOR
SELECT REQ_ID, REQ_TYPE_STATUS FROM FIRSTTABLE
WHERE FIRSTTABLE.REQ_ID = REQUESTID
AND (REQ_STATUS = 'D' OR REQ_STATUS = 'A');
ELSE
-- Search for the request from the second table
SELECT COUNT(REQ_ID) INTO REQUESTFOUND FROM SECONDTABLE
WHERE SECONDTABLE.REQ_ID = REQUESTID;
IF(REQUESTFOUND > 0) THEN
-- Select the request details from second table
OPEN REQUEST FOR
SELECT REQ_TYPE, '-' AS REQ_TYPE_STATUS FROM SECONDTABLE
WHERE SECONDTABLE.REQ_ID = REQUESTID;
ELSE
-- Get the request from third table (will return as blank if nothing found)
OPEN REQUEST FOR
SELECT REQ_TYPE, '-' AS REQ_TYPE_STATUS FROM THIRDTABLE
WHERE THIRDTABLE.REQ_ID = REQUESTID;
END IF;
END IF;