Szukaj…
Składnia
- Kursor cursor_name Czy your_select_statement
- Kursor nazwa_ kursora (param TYPE) Czy twoja_wybrana_stat_nazwa_parametru
- DLA x w pętli ( twoja_selekcja_opcji ) ...
Uwagi
Zadeklarowane kursory są trudne w użyciu i w większości przypadków powinieneś preferować pętle FOR
. Co ciekawe w kursorach w porównaniu z prostymi pętlami FOR
, możesz je sparametryzować.
Lepiej jest unikać robienia pętli z PL / SQL i kursorów zamiast korzystania z Oracle SQL. Jednak dla osób przyzwyczajonych do języka proceduralnego zrozumienie może być znacznie łatwiejsze.
Jeśli chcesz sprawdzić, czy rekord istnieje, a następnie wykonać różne czynności w zależności od tego, czy rekord istnieje, czy nie, warto użyć instrukcji MERGE
w czystych zapytaniach SQL typu ORACLE zamiast używać pętli kursora. (Pamiętaj, że MERGE
jest dostępny tylko w wersjach Oracle> = 9i).
Sparametryzowany kursor „pętli 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;
/
Ukryty kursor „pętli 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;
/
- Pierwszą zaletą jest brak żmudnej deklaracji (pomyśl o tym okropnym „KURSORZE”, który miałeś w poprzednich wersjach)
- drugą zaletą jest to, że najpierw budujesz wybrane zapytanie, a następnie, gdy masz to, czego chcesz, możesz natychmiast uzyskać dostęp do pól swojego zapytania (
x.<myfield>
) w pętli PL / SQL - Pętla otwiera kursor i pobiera jeden rekord na raz dla każdej pętli. Na końcu pętli kursor jest zamknięty.
- Niejawne kursory są szybsze, ponieważ praca interpretera rośnie wraz z wydłużaniem się kodu. Im mniej kodu, tym mniej pracy musi wykonać tłumacz.
Praca z SYS_REFCURSOR
SYS_REFCURSOR
może być używany jako typ zwracany, gdy trzeba łatwo obsłużyć listę zwróconą nie z tabeli, ale dokładniej z funkcji:
funkcja zwraca kursor
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;
/
i jak go używać:
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;
/
Obsługa KURSORA
- Zadeklaruj kursor, aby zeskanować listę rekordów
- Otwórz to
- Pobierz bieżący rekord do zmiennych (zwiększa to pozycję)
- Użyj
%notfound
aby wykryć koniec listy - Nie zapomnij zamknąć kursora, aby ograniczyć zużycie zasobów w bieżącym kontekście
-
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;
/