Recherche…
Syntaxe
- Curseur nom_curseur est votre_sélection_de_sélection
- Curseur nom_curseur ( paramètre TYPE) est-ce que votre_select_statement_using_param
- FOR x in ( your_select_statement ) LOOP ...
Remarques
Les curseurs déclarés sont difficiles à utiliser et vous devriez préférer les boucles FOR
dans la plupart des cas. Ce qui est très intéressant dans les curseurs par rapport aux boucles FOR
simples, c'est que vous pouvez les paramétrer.
Il est préférable d'éviter les boucles avec PL / SQL et les curseurs plutôt que d'utiliser Oracle SQL. Cependant, pour les personnes habituées au langage procédural, il peut être beaucoup plus facile à comprendre.
Si vous voulez vérifier si un enregistrement existe, puis faire des choses différentes selon que l'enregistrement existe ou non, il est logique d' utiliser des instructions MERGE
dans des requêtes SQL ORACLE pures au lieu d'utiliser des boucles de curseur. (Veuillez noter que MERGE
est uniquement disponible dans les versions Oracle> = 9i).
Curseur paramétrable "FOR loop"
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;
/
Curseur implicite "FOR loop"
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;
/
- Le premier avantage est qu'il n'y a pas de déclaration fastidieuse à faire (pensez à cette horrible chose "CURSOR" que vous aviez dans les versions précédentes)
- deuxième avantage est que vous construisez d'abord votre requête select, puis quand vous avez ce que vous voulez, vous pouvez immédiatement accéder aux champs de votre requête (
x.<myfield>
) dans votre boucle PL / SQL - La boucle ouvre le curseur et récupère un enregistrement à la fois pour chaque boucle. A la fin de la boucle, le curseur est fermé.
- Les curseurs implicites sont plus rapides car le travail de l'interpréteur augmente à mesure que le code s'allonge. Le moins de code, moins l'interprète doit travailler.
Travailler avec SYS_REFCURSOR
SYS_REFCURSOR
peut être utilisé comme type de retour lorsque vous devez manipuler facilement une liste renvoyée non pas par une table, mais plus précisément par une fonction:
fonction renvoyant un curseur
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;
/
et comment l'utiliser:
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;
/
Manipulation d'un CURSEUR
- Déclarez le curseur pour numériser une liste d'enregistrements
- L'ouvrir
- Récupère l'enregistrement actuel dans des variables (cette position d'incrémentation)
- Utilisez
%notfound
pour détecter la fin de la liste - N'oubliez pas de fermer le curseur pour limiter la consommation de ressources dans le contexte actuel
-
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;
/