Bonjour,
nous utilisons du sql dynamique pour la construction de nos requetes dans des procédures et des packages oracles.
Suite à la lecture de plusieurs articles, dont celui ci
http://www.rittman.net/archives/000832.html
nous désirons utiliser les variables "bindées" afin d'amélirorer les performances globales.
Ci dessous un exemple simpliste de ce que nous faisons et de ce que nous voudrions faire :
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
CREATE OR REPLACE PROCEDURE exemple(
 pi_id_user  IN	NUMBER,
 cr_cursor OUT Cr_Rpt_Cursors.cr_rpt_cursor   -- type REF CURSOR
)
AS
 l_qry VARCHAR2(2000);
BEGIN
 
/* ancienne méthode sans utilisation de bind variables
l_qry :='SELECT LOGIN FROM T_USERS where ID_USER=' || pi_id_user;
   OPEN cr_cursor FOR l_qry ;
*/
 
 
--nouvelle méthode 
l_qry :='SELECT LOGIN FROM T_USERS where ID_USER=:bind_id_user';
   OPEN cr_cursor FOR l_qry USING pi_id_user ;
 
 END;

ceci marche très bien,
Seul GROS problème, c'est exemple est trop simple et en fait la génération de notre chaine sql dynamique est plutot du style :



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
20
21
22
23
24
25
26
27
28
29
30
CREATE OR REPLACE PROCEDURE exemple(
 pi_id_user  IN	NUMBER,
 pi_param1  IN	NUMBER,
 pi_param2  IN	NUMBER,
 cr_cursor   OUT Cr_Rpt_Cursors.cr_rpt_cursor   -- type REF CURSOR
)
AS
 l_qry VARCHAR2(2000);
BEGIN
 
l_qry :='SELECT LOGIN FROM T_USERS where 1=1';
 
IF pi_id_user  != -1 THEN
	l_qry:=l_qry || ' AND ID_USER=:bind_pi_id_user';
END IF;
 
IF pi_param1  != -1 THEN
	l_qry:=l_qry || ' AND ID_PAYS = :bind_pi_param1';
END IF;
 
IF pi_param2  != -1 THEN
	l_qry:=l_qry || ' AND ID_VILLE = :bind_pi_param2';
END IF;
 
--[...]
 
-- impossible de faire le bind ci dessous car je ne suis pas sûr d'avoir une 1,2 ou 3 variable à binder
  OPEN cr_cursor FOR l_qry USING pi_id_user, pi_param1 ,pi_param2 ;
 
 END;
J'ai un probleme dans la clause USING ci dessus car je ne suis pas sûr d'avoir une 1,2 ou 3 variable à passer (puisque la chaine générée dépend des valeurs des parametres)

Il faudrait en fait que je puisse renseigner les variables :bind_pi_param1, :bind_pi_param2 au moment de la création de la chaine (dans le if)

j'ai essayé
Code : Sélectionner tout - Visualiser dans une fenêtre à part
:bind_pi_param2:=pi_param2
mais le compilateur n'en veut pas

Si je met directement dans la chaine générée :pi_param2 le message est au moment de l'execution: ORA-01008: not all variables bound

J'ai bien vu la possibilité d'utiliser le package dbms_sql , mais la syntaxe est beaucoup plus lourde et serait plus lente dixit :
http://sheikyerbouti.developpez.com/execute_immediate/

Impossible de trouver sur le net d'exemples correspondant à mon pb.
Soit je suis passé completement a coté et c'est tellement simple que personne n'a eu l'idée de poser la question, soit j'ai mal cherché (dans ces 2 cas désolé de la question ), soit il n'y a pas de solution...mais ça m'étonne quand même soit la vérité est ailleur, mais dans ce cas.. OU..?


Merci pour toute aide ou conseil pour résoudre ce problème (en espérant ne pas avoir été trop long dans la description )

Pour info, outils utilisés
[Oracle9i Enterprise Edition Release 9.2.0.2.0]
[TOAD 8.5.3.2]