获取PL / SQL游标for循环以使用输入变量?

时间:2013-04-25 18:19:33

标签: sql oracle loops plsql

我必须生成PL / SQL块,它接受一个整数的输入,其中n(1≤n≤100)并显示男性和女性最常用的名称。如果输入的数字超出该范围,则显示无效输入。我创建了一个名为流行名称的表,其中包含100个最受欢迎的男性和女性名字。我正在努力使用我的FOR循环并让它与用户输入一起工作。我的代码如下:

ACCEPT p_1 prompt 'please enter an integer between 1 and 100'

DECLARE
    CURSOR name_cur IS
            SELECT    rank, male_given_name, female_given_name
            FROM          popular_names
          ORDER BY  rank;

        v_nrank         popular_names.rank%TYPE := &p_1;
        v_nmale           popular_names.male_given_name%TYPE;
        v_nfemale     popular_names.female_given_name%TYPE;



BEGIN   
      OPEN name_cur;
      FETCH name_cur INTO v_nrank, v_nmale, v_nfemale;

      IF name_cur%FOUND THEN
        DBMS_OUTPUT.PUT_LINE('Rank     Male Given Name     Female Given Name');
        DBMS_OUTPUT.PUT_LINE('----------------------------------------------');


        FOR i IN 1..v_nrank LOOP
            DBMS_OUTPUT.PUT_LINE((RPAD(v_nrank, 18) || '  ' || 
                (RPAD(v_nmale, 18) || '  ' || v_nfemale)));
                FETCH name_cur INTO v_nrank, v_nmale, v_nfemale; 
              EXIT WHEN name_cur%NOTFOUND;
        END LOOP;


      ELSE
          DBMS_OUTPUT.PUT_LINE('Invalid number!');
      END IF;

        CLOSE name_cur;
END;

1 个答案:

答案 0 :(得分:1)

不需要光标。或者在游标中使用类似的查询。您可以使用Rownum伪列代替Row_Number()函数:

SELECT * FROM
(
 SELECT deptno
      , empno
      , ename
      , Row_Number() OVER (ORDER BY empno) AS row_seq -- can order/partition by any field 
      -- , Rownum AS row_seq
  FROM scott.emp
) 
WHERE row_seq BETWEEN 1 AND 10 -- any integer as in your example --
/


DECLARE
  CURSOR e_cur 
  IS
  SELECT * FROM
  (
   SELECT deptno
     , empno
     , ename
     , Row_Number() OVER (ORDER BY empno) AS row_seq --'AS' is for clarity-not required
     --, Rownum AS row_seq 
    FROM scott.emp
   ) 
  WHERE row_seq BETWEEN 1 AND 10 -- any integer, can use variable like &num --
  ORDER BY row_seq;

  v_deptno  scott.dept.deptno%TYPE;
  v_emp_no  scott.emp.empno%TYPE;
  v_name    scott.emp.ename%TYPE;
  v_rank    NUMBER;
BEGIN
  OPEN e_cur;
  LOOP
    FETCH e_cur INTO v_deptno, v_emp_no, v_name, v_rank;
    EXIT WHEN e_cur%NOTFOUND;
      dbms_output.put_line(v_rank||chr(9)||v_deptno||chr(9)||v_emp_no||chr(9)||v_name);
  END LOOP;
 CLOSE e_cur;
END;
/