代码之家  ›  专栏  ›  技术社区  ›  Zain Qurashi

我可以在游标周围使用if语句还是在fetch中使用while循环

  •  0
  • Zain Qurashi  · 技术社区  · 8 年前

    我在解决这个问题时遇到了问题。

    如果n=0,则显示所有行(性别、秩、给定名称和 tbl\u baby\u name表中出现的次数)。对输出进行排序 按性别升序,然后排名。

    出现次数)在tbl\u baby\u 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 回复  |  直到 8 年前
        1
  •  1
  •   APC    8 年前

    “它只是不允许我在光标周围放置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