수색…
통사론
- 커서 cursor_name 은 your_select_statement입니다.
- 커서 cursor_name (param TYPE) your_select_statement_using_param 인가
- FOR x in ( your_select_statement ) LOOP ...
비고
선언 된 커서 는 사용하기 어렵고 대부분의 경우 FOR
루프를 선호해야합니다. 간단한 FOR
루프와 비교할 때 커서에서 흥미로운 점은 매개 변수화가 가능하다는 것입니다.
어쨌든 Oracle SQL을 사용하는 대신 PL / SQL과 커서로 루프를 수행하지 않는 것이 좋습니다. 그러나 절차 적 언어에 익숙한 사람들은 이해하기가 훨씬 쉽습니다.
레코드 존재 여부를 확인한 다음 레코드 존재 여부에 따라 다른 작업을 수행 하려면 커서 루프를 사용하는 대신 순수 ORACLE SQL 쿼리에서 MERGE
문 을 사용하는 것이 좋습니다. ( MERGE
는 오라클 릴리즈> 9i에서만 사용 가능합니다).
매개 변수화 된 "FOR 루프"커서
DECLARE
CURSOR c_emp_to_be_raised(p_sal emp.sal%TYPE) IS
SELECT * FROM emp WHERE sal < p_sal;
BEGIN
FOR cRowEmp IN c_emp_to_be_raised(1000) LOOP
dbms_Output.Put_Line(cRowEmp .eName ||' ' ||cRowEmp.sal||'... should be raised ;)');
END LOOP;
END;
/
암시 적 "FOR 루프"커서
BEGIN
FOR x IN (SELECT * FROM emp WHERE sal < 100) LOOP
dbms_Output.Put_Line(x.eName ||' '||x.sal||'... should REALLY be raised :D');
END LOOP;
END;
/
- 첫 번째 장점은 지루한 선언을 할 필요가 없다는 것입니다 (이전 버전에서 가지고 있던이 끔찍한 "CURSOR"
- 두 번째 장점은 선택한 쿼리를 먼저 작성한 다음 원하는 것을
x.<myfield>
으면 즉시 PL / SQL 루프에서 쿼리 필드 (x.<myfield>
)에 액세스 할 수 있다는 것입니다 - 루프는 커서를 열고 모든 루프마다 한 번에 하나의 레코드를 가져옵니다. 루프의 끝에서 커서가 닫힙니다.
- 암시 적 커서는 코드가 길어질수록 인터프리터의 작업이 커지기 때문에 더 빠릅니다. 코드가 적을수록 통역사의 업무가 줄어 듭니다.
SYS_REFCURSOR로 작업하기
SYS_REFCURSOR
는 테이블이 아닌 함수에서 리턴 된리스트를 쉽게 처리해야 할 때 리턴 유형으로 사용할 수 있습니다.
커서를 반환하는 함수
CREATE OR REPLACE FUNCTION list_of (required_type_in IN VARCHAR2)
RETURN SYS_REFCURSOR
IS
v_ SYS_REFCURSOR;
BEGIN
CASE required_type_in
WHEN 'CATS'
THEN
OPEN v_ FOR
SELECT nickname FROM (
select 'minou' nickname from dual
union all select 'minâ' from dual
union all select 'minon' from dual
);
WHEN 'DOGS'
THEN
OPEN v_ FOR
SELECT dog_call FROM (
select 'bill' dog_call from dual
union all select 'nestor' from dual
union all select 'raoul' from dual
);
END CASE;
-- Whit this use, you must not close the cursor.
RETURN v_;
END list_of;
/
및 사용 방법 :
DECLARE
v_names SYS_REFCURSOR;
v_ VARCHAR2 (32767);
BEGIN
v_names := list_of('CATS');
LOOP
FETCH v_names INTO v_;
EXIT WHEN v_names%NOTFOUND;
DBMS_OUTPUT.put_line(v_);
END LOOP;
-- here you close it
CLOSE v_names;
END;
/
커서 처리하기
- 레코드 목록을 스캔하려면 커서를 선언하십시오.
- 열어 봐
- 현재 레코드를 변수로 가져옵니다 (이것은 위치를 증가시킵니다).
- 목록의 끝을 감지하려면
%notfound
를 사용하십시오. - 커서를 닫아 현재 상황에서 리소스 소비를 제한하는 것을 잊지 마십시오.
-
DECLARE
CURSOR curCols IS -- select column name and type from a given table
SELECT column_name, data_type FROM all_tab_columns where table_name='MY_TABLE';
v_tab_column all_tab_columns.column_name%TYPE;
v_data_type all_tab_columns.data_type%TYPE;
v_ INTEGER := 1;
BEGIN
OPEN curCols;
LOOP
FETCH curCols INTO v_tab_column, v_data_type;
IF curCols%notfound OR v_ > 2000 THEN
EXIT;
END IF;
dbms_output.put_line(v_||':Column '||v_tab_column||' is of '|| v_data_type||' Type.');
v_:= v_ + 1;
END LOOP;
-- Close in any case
IF curCols%ISOPEN THEN
CLOSE curCols;
END IF;
END;
/
Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow