2013-03-01 8 views
2

이 코드의 잘못된 점을 누군가에게 알려주시겠습니까? 내 목표는 직원의 이름을 전달하는 프로 시저를 작성하고 직원 테이블의 모든 이름과 급여를 VARRAY로로드 한 다음 화면에 이름과 급여를 인쇄하는 것입니다.커서가있는 pl/sql 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; 
+0

1. 사용하지 않으면 프로 시저에 매개 변수를 전달하는 이유는 무엇입니까? 2. 왜 커서 루프에서 작업을 할 수있을 때 VARRAY를 귀찮게합니까? 3. 출력이 표시되지 않으면 'serveroutput on'을 설정하는 것이 좋습니다. – Glenn

+0

어떤 오류가 발생 했습니까? – Allan

+0

@ 글렌 나는 그가 어떻게하는지 배우고 있으며,이 파트를 완성한 후에 매개 변수와 Varray를 사용할 것이라고 생각한다. –

답변

9

첫 번째는 PL/SQL 컬렉션이 0 기반이 아닙니다. 카운터가 0을 쳐다 보았 기 때문에 아래 첨자가 한계 오차를 벗어납니다.이 솔루션에는 카운터가 필요하지 않습니다. 계속 사용하려면 첫 번째 예제를 참조하십시오. 하지만 내가 너라면 두 번째 예를 쓸거야.

두 번째로 VARRAY가 하나의 행을 포함하도록 확장 되었기 때문에 루프 앞에서 VARRAY를 확장했습니다. 카운트 오류를 ​​넘어서 아래 첨자가 발생합니다. 루프가 시작될 때마다 루프를 확장해야 각 반복마다 Varray가 확장됩니다.

Thid, 당신은 PUT_LINE 전체 VARRAY 일 수 없습니다. Varray의 요소는 put_line입니다. 따라서이 예에서보다는 dbms_output.put_line(x_varray_emp(i)) 대신이 사용 dbms_output.put_line(x_varray_emp(i).ename || ' makes $' || x_varray_emp(i).sal)

넷째 : 당신의 emp 테이블이있는 14 개 이상의 기록이있는 경우, 귀하의 VARRAY(14)이 제한 오류의 외부 첨자의 원인이됩니다. VARRAY는 최대 크기가 한계 값으로 설정되어 있는데,이 경우에는 14가됩니다.이 예제에서는 제한된 경계에 대해 걱정하지 않기 위해 일반 중첩 테이블 (TYPE nested_emp IS TABLE OF emp_cur%ROWTYPE)을 사용했습니다 (기술적으로 중첩 테이블에는 최대 2147483647 일명 PLS_INTEGER). VA 이상으로 NT를 사용하려면 아래의 세 번째 해법을 사용하십시오.

다음과 같이 실행하면됩니다.

v_counter NUMBER := 0v_counter NUMBER := 1으로 변경하십시오. 이에 BODY에

변경 :

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; 

실제로, 카운터가 필요하지 않습니다.

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를 통해이 문제에 대한 중첩 테이블을 사용하는 것이 선호 : 당신이 그것을 포기하고자하는 경우, 대신 VARRAY의 COUNT 방법을 사용합니다. 원하는 경우 여기에 해결책이 있습니다.

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; 
+0

중첩 테이블을 사용하는 경우 BULK COLLECT가 더 나은 접근 방법입니다. 그러나이 작업에는 컬렉션이 필요하지 않습니다. 간단하게 FOR CURSOR 루프 만 있으면됩니다. 그러한 숙제 연습의 쓸모없는 것을 보여주는 것 : 언어의 메커니즘을 가르치지 만 올바르게 사용하는 방법은 가르쳐주지 않습니다. 그래서 모든 학생들은 실제로 나쁜 PL/SQL을 작성하는 방법을 배웁니다. – APC