PL / SQl错误。无法弄清楚

时间:2014-09-15 16:35:00

标签: sql plsql oracle10g

我试图按照以下说明执行代码。但不知怎的,我不能让它工作。我是PL / SQl的新手。任何暗示都很有价值,谢谢

排名表有:

rankID   Number
name     Varchar2(255 BYTE)

/ * 编写PL / SQL程序(匿名块),打印出所有等级的列表(ID 和名称)所有等级ID从100到110.如果没有出现等级ID(xxx) 在排名表中,程序应该打印出来:没有可用于ID的排名: XXX

* /

--set serveroutput on
DECLARE
    rank_id NUMBER;
    rank_name VARCHAR2(255);
    loopcount NUMBER;
BEGIN
    loopcount :=100;
    FOR k IN 100..110 
    LOOP
        SELECT rankID, name
        INTO rank_id, rank_name
        FROM rank
        WHERE rankID=loopcount;
            DBMS_OUTPUT.PUT_LINE(rank_id||'     '|| rank_name); 
            loopcount := loopcount + 1;
    END LOOP;

EXCEPTION
    WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE('NO RANK AVAILABLE for ID: '||rank_id);
END;
/

以下是我得到的内容。它不按照它的方式工作

Server output:
100     Chefpilot
NO RANK AVAILABLE for ID: 100

DECLARE executed successfully

Execution time: 0.26s

2 个答案:

答案 0 :(得分:2)

在这种情况下不需要循环,您可以使用outer joincase语句和数字表来执行此操作:

WITH CTE (RankId) AS (
  SELECT 100 RankId
  FROM DUAL
  UNION ALL
  SELECT RankId + 1
  FROM CTE
  WHERE RankId < 110
) 
SELECT t.RankId, COALESCE(r.Name, 'Does not exist') Name,
  CASE 
    WHEN r.RankId IS NULL THEN 'No rank available for: ' || t.RankId 
    ELSE r.RankId || ' ' || r.Name
  END Description
FROM CTE t
  LEFT JOIN rank r ON t.RankId = r.RankId 
ORDER BY t.RankId

答案 1 :(得分:0)

@ sgeddes的方法更好,但是为了解释你所看到的,如果你确实想要使用你的机制,那么你需要在内部块中捕获异常。目前异常处理程序在循环之外,因此您看到的第一个错误会终止循环。内部区块:

DECLARE
    rank_id NUMBER;
    rank_name VARCHAR2(255);
BEGIN
    FOR loopID IN 100..110 
    LOOP
        BEGIN -- inner block
            SELECT rankID, name
            INTO rank_id, rank_name
            FROM rank
            WHERE rankID=loopID;

            DBMS_OUTPUT.PUT_LINE(rank_id||'     '|| rank_name); 
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                DBMS_OUTPUT.PUT_LINE('NO RANK AVAILABLE for ID: '||loopID);
        END; -- inner block
    END LOOP;   
END;
/

现在,如果ID不存在,则捕获异常,打印消息,内部块退出;这意味着循环在下一次迭代中继续。 (我还删除了额外的loopcount,并一直使用loopID for和两个引用。