有人能告诉我这个密码有什么问题吗?我的目标是编写一个传递员工姓名的过程,将employee表中的所有姓名和薪水加载到varray中,然后在屏幕上打印出姓名和薪水。

CREATE OR REPLACE PROCEDURE VARRAY_Q2
(
  PNAME IN VARCHAR2
, PSAL OUT NUMBER
) AS

--declare and create cursor

CURSOR emp_cur IS
SELECT ename,sal
FROM EMP;

  TYPE varray_emp IS VARRAY(14) OF emp_Cur%ROWTYPE;

  --Creating new instance of varray
  x_varray_emp varray_emp := varray_emp();
  v_counter NUMBER := 0;

BEGIN

  x_varray_emp.EXTEND;

  FOR empRecs IN emp_Cur LOOP

  --Insert data into the varray
  x_varray_emp(v_counter) := empRecs;

  dbms_output.put_line(v_counter);

  v_counter := v_counter + 1;
  END LOOP;

  --Loop through the varray and print out all the elements
  FOR i IN x_varray_emp.FIRST .. x_varray_emp.LAST
  LOOP
  dbms_output.put_line(x_varray_emp(i));
  END LOOP;

END;

最佳答案

第一:pl/sql集合不是基于0的。这将抛出下标超出限制的错误,因为您的计数器盯着0。您也不需要计数器来解决此问题。如果要继续使用它,请参见第一个示例。但如果我是你,我会用第二个例子。
其次,在循环之前扩展了varray。这将抛出一个下标beyond count错误,因为varray只被扩展到容纳一行。您需要在循环开始时扩展它,以便在每次迭代时扩展varray。
这,你不能把瓦雷整成一个。你必须PUT_LINE瓦雷的元素。所以在这个例子中,不要使用这个:put_line
第四:如果emp表中有超过14条记录,则dbms_output.put_line(x_varray_emp(i))将导致下标超出限制错误。varray有一个最大大小设置(有界限制),在您的情况下是14。在这个例子中,我将使用一个规则嵌套表(dbms_output.put_line(x_varray_emp(i).ename || ' makes $' || x_varray_emp(i).sal)),以便不担心有界限制(技术上,嵌套表最多有2147483647个AKA PLSY整数)。如果您愿意在VA上使用NT,请使用下面的第三种解决方案。
做以下的事情,它就会起作用。
VARRAY(14)更改为TYPE nested_emp IS TABLE OF emp_cur%ROWTYPE
将主体中的内容更改为:

BEGIN
    FOR empRecs IN emp_Cur LOOP
        x_varray_emp.EXTEND;
        --Insert data into the varray
        x_varray_emp(v_counter) := empRecs;

        dbms_output.put_line(v_counter);

        v_counter := v_counter + 1;
    END LOOP;
    --Loop through the varray and print out all the elements
    FOR i IN x_varray_emp.FIRST .. x_varray_emp.LAST LOOP
        dbms_output.put_line(x_varray_emp(i).ename || ' Makes $' || x_varray_emp(i).sal);
    END LOOP;
END;

实际上,你不需要柜台。如果您愿意放弃它,请改用varray的v_counter NUMBER := 0方法:
BEGIN


    FOR empRecs IN emp_Cur LOOP
        x_varray_emp.EXTEND;

        --Insert data into the varray
        x_varray_emp(x_varray_emp.count) := empRecs;

        dbms_output.put_line(x_varray_emp.count);


    END LOOP;

    --Loop through the varray and print out all the elements
    FOR i IN x_varray_emp.FIRST .. x_varray_emp.LAST LOOP
        dbms_output.put_line(x_varray_emp(i).ename || ' Makes $' || x_varray_emp(i).sal);
    END LOOP;


END;

与varray相比,我更希望使用嵌套表来解决此问题。如果你愿意,以下是解决方案:
DECLARE

    CURSOR emp_cur IS SELECT ename,sal FROM EMP;
    TYPE nestedtable_emp IS TABLE OF emp_cur%ROWTYPE;

    x_nestedtable_emp nestedtable_emp := nestedtable_emp();
BEGIN


    FOR empRecs IN emp_Cur LOOP
        x_nestedtable_emp.EXTEND;

        --Insert data into the varray
        x_nestedtable_emp(x_nestedtable_emp.count) := empRecs;

        dbms_output.put_line(x_nestedtable_emp.count);


    END LOOP;

    --Loop through the varray and print out all the elements
    FOR i IN x_nestedtable_emp.FIRST .. x_nestedtable_emp.LAST LOOP
        dbms_output.put_line(x_varray_emp(i).ename || ' Makes $' || x_varray_emp(i).sal);
    END LOOP;


END;

09-25 22:21