使用游标在捕获的异常中执行选择操作

时间:2014-03-21 14:29:33

标签: plsql

我试图编写一个存储过程,它接受一个I​​D的输入,然后使用不同的标准搜索该项目的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中),它不会返回任何行。

有什么想法吗?

1 个答案:

答案 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;