Bonjour,
j'ai une question un peu "débutant" à vous poser:
Qu'elle est la différence sous le capot d'Oracle ( de stockage des plans d'exécution des requêtes, le moment du calcul du plan d'exécution, moment du passage des paramètres, passage de paramètres entre moteurs PL/SQL et moteurs SQL etc...) entre:
1 - Utilisation d'un REF CURSOR avec passage de paramètre par USING
2 - Utilisation d'un REF CURSOR avec passage de paramètre à la main par concaténation
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 declare 2 TYPE CURSOR_CLIENTS IS REF CURSOR; 3 c_clients CURSOR_CLIENTS; 4 v_client CLIENTS%ROWTYPE; 5 v_pays CLIENTS.PAYS%TYPE := 'France'; 6 v_SQL varchar2(200) 7 := 'SELECT * FROM CLIENTS WHERE PAYS = :a_pays'; 8 begin 9 open c_clients FOR v_SQL USING v_pays; 10 loop 11 fetch c_clients into v_client; 12 exit when c_clients%NOTFOUND; 13 dbms_output.put_line( 'Client : '|| 14 v_client.societe||' '|| v_client.ville); 15 end loop; 16 close c_clients; 17 end; 18 /
3 - Utilisation d'un curseur paramétré
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 declare 2 TYPE CURSOR_CLIENTS IS REF CURSOR; 3 c_clients CURSOR_CLIENTS; 4 v_client CLIENTS%ROWTYPE; 5 v_pays CLIENTS.PAYS%TYPE := 'France'; 6 v_SQL varchar2(200) 7 := 'SELECT * FROM CLIENTS WHERE PAYS = '; 8 begin 9 open c_clients FOR v_SQL || '''' || v_pays || '''' ; 10 loop 11 fetch c_clients into v_client; 12 exit when c_clients%NOTFOUND; 13 dbms_output.put_line( 'Client : '|| 14 v_client.societe||' '|| v_client.ville); 15 end loop; 16 close c_clients; 17 end; 18 /
Pour vous montrer le genre de réponses que j'attends je vous confie mon intuition:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 declare 2 CURSOR c_clients (p_pays CLIENTS.PAYS%TYPE) IS 3 SELECT * FROM CLIENTS WHERE PAYS = p_pays; 4 5 v_client CLIENTS%ROWTYPE; 6 v_pays CLIENTS.PAYS%TYPE := 'France'; 7 8 begin 9 open c_clients (v_pays); 10 loop 11 fetch c_clients into v_client; 12 exit when c_clients%NOTFOUND; 13 dbms_output.put_line( 'Client : '|| 14 v_client.societe||' '|| v_client.ville); 15 end loop; 16 close c_clients; 17 end; 18 /
1 - plan d'exécution calculé à l'exécution du bloc , plan d'exécution est calculé une fois pour toutes et réutilisable lors des appels suivants du même bloc.
2 - interprété à l'exécution du bloc, plan d'exécution non réutilisable ou non conservé en mémoire (par le driver client Oracle ? par la base?).
3 - plan d'exécution calculé à la compilation du bloc. Plus rapide que 1 et 2 car moins de travail à l'exécution (une bonne partie du travail étant déjà faite à la compilation). Ressemble à l'appel d'une Procédure (sauf qu'elle s'appelle CURSOR qqch) appelée depuis notre bloc.
Pour ceux qui connaissent la Java. Je vois (1) comme l'appel d'un PreparedStatement, (2) comme l'appel d'un Statement (3) comme l'appel d'une procédure stockée.
Merci beaucoup de m'avoir lu et d'éclairer ma lanterne.
Partager