我可以使用带有fetch的游标或while循环使用if语句

时间:2017-10-03 00:15:31

标签: sql oracle oracle-sqldeveloper

我遇到了解决这个问题的问题。

  

如果n < 0,显示错误消息“无效的数字!”。

     

如果n = 0,则显示所有行(Sex,Rank,Given_Name和   number_of_Occurrences)在tbl_baby_name表中。对输出进行排序   按性别按升序排列。然后排名。

     

如果n> 0,显示所有行(Sex,Rank,Given_Name和   Number_of_Occurrences)在tbl_baby_name表中具有等级≤n。   按性别按升序对输出进行排序,然后排名。

如何仅显示小于用户输入数量的婴儿等级。我有所有婴儿的输出,但我只想要排名低于用户输入的排名。

每当我尝试在光标周围放置一个if语句时,它会给我一个错误。它也不会让我在fetch语句周围添加一个while循环。

有人可以帮忙!

ACCEPT p_1 PROMPT 'Enter  a number :'
DECLARE
        v_n                    NUMBER := &p_1;
        v_baby_rank            TBL_BABY_NAME.RANK%TYPE;
        v_baby_sex             VARCHAR(80);
        v_baby_name            TBL_BABY_NAME.GIVEN_NAME%TYPE;
        v_baby_numoc           TBL_BABY_NAME.NUMBER_OF_OCCURRENCES%TYPE;

    CURSOR c_baby IS
            SELECT         rank, CASE sex WHEN 'M' THEN 'Male' ELSE 'Female' END, GIVEN_NAME, NUMBER_OF_OCCURRENCES
            FROM           TBL_BABY_NAME
            ORDER BY       sex,rank;
BEGIN
    if v_n < 0 Then 
        DBMS_OUTPUT.PUT_LINE('Invalid Number');
    Else
        OPEN c_baby;
        FETCH c_baby 
        INTO v_baby_rank, v_baby_sex, v_baby_name, v_baby_numoc;
        DBMS_OUTPUT.PUT_LINE( RPAD('Sex',10) || RPAD('Rank',10) || RPAD('Given Name',15) || ('Number of Occurrences') );
        DBMS_OUTPUT.PUT_LINE('===========================================================');
        while c_baby%FOUND loop
            DBMS_OUTPUT.PUT_LINE(RPAD(v_baby_sex, 10) || RPAD(v_baby_rank,10) || RPAD(v_baby_name,30) || v_baby_numoc);
            FETCH c_baby 
            INTO v_baby_rank, v_baby_sex, v_baby_name, v_baby_numoc;
        END LOOP;
        CLOSE c_baby;
    END IF;
END;

My output

1 个答案:

答案 0 :(得分:1)

  

“它只是不允许我在光标周围放置一个if语句。不会执行”

满足要求的最简单方法是:

    while c_baby%FOUND loop
        if  v_n = 0 
        or  c_baby.rank < v_n 
        then
            DBMS_OUTPUT.PUT_LINE(RPAD(v_baby_sex, 10) || RPAD(v_baby_rank,10) || RPAD(v_baby_name,30) || v_baby_numoc);
        end if;
        FETCH c_baby 

它选择所有记录但仅显示与输入标准匹配的记录。

如果性能是一个问题 - 不是你的作业,但它在现实生活中很重要 - 那么你可能想要选择一个过滤的结果集,而不是选择所有内容并丢弃不需要的行。在这种情况下,您将使用游标变量:

.....
    c_baby sys_refcursor;
BEGIN
    if v_n < 0 Then 
        DBMS_OUTPUT.PUT_LINE('Invalid Number');
    Elsif v_n > 0 Then 
        OPEN c_baby for
            SELECT         rank, CASE sex WHEN 'M' THEN 'Male' ELSE 'Female' END, GIVEN_NAME, NUMBER_OF_OCCURRENCES
            FROM           TBL_BABY_NAME
            where rank < v_n
            ORDER BY       sex,rank;
    Else 
        OPEN c_baby for
            SELECT         rank, CASE sex WHEN 'M' THEN 'Male' ELSE 'Female' END, GIVEN_NAME, NUMBER_OF_OCCURRENCES
            FROM           TBL_BABY_NAME
            ORDER BY       sex,rank;
    end if;
    FETCH c_baby 
    INTO .... -- the rest of your posted code

使用游标变量允许我们将不同的结果集注入标准处理集。可以通过使用动态SQL来避免SELECT中的重复代码,但这可能超出了简要说明。