Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 28/02/2008, 14h57   #1
Rédacteur

 
Avatar de Louis-Guillaume Morand
 
Homme Louis-Guillaume MORAND
Consultant @ Microsoft
Inscription : mars 2003
Messages : 10 713
Détails du profil
Informations personnelles :
Nom : Homme Louis-Guillaume MORAND
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant @ Microsoft
Secteur : Conseil

Informations forums :
Inscription : mars 2003
Messages : 10 713
Points : 15 946
Points : 15 946
Par défaut Simplification de requête

Voici ma requête actuelle
Code :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
IF (p_date = '')
      THEN
         BEGIN
            OPEN cur FOR
               SELECT *
                 FROM t_alerts a, t_alert_base base, t_alert_call CALL
                WHERE a.pk_alert = base.pk_alert
                  AND CALL.pk_option = base.pk_option
                  AND (p_obj IS NULL OR CALL.option_object = p_obj)
                  AND (p_prd IS NULL OR CALL.product = p_prd)
                  AND (p_ref IS NULL OR base.option_ref = p_ref)
                  AND (p_file IS NULL OR a.pk_file = p_file)
                  AND (p_book IS NULL OR CALL.book IN (SELECT pk_book
                                                         FROM t_book
                                                        WHERE lbl = p_book))
                  AND (   p_cty IS NULL
                       OR CALL.counterparty IN (SELECT pk_counterparty
                                                  FROM t_counterparty
                                                 WHERE lbl = p_cty)
                      );
         END;
      ELSIF (p_date = '=')
      THEN
         BEGIN
            OPEN cur FOR
               SELECT *
                 FROM t_alerts a, t_alert_base base, t_alert_call CALL
                WHERE a.pk_alert = base.pk_alert
                  AND CALL.pk_option = base.pk_option
                  AND (p_obj IS NULL OR CALL.option_object = p_obj)
                  AND (p_prd IS NULL OR CALL.product = p_prd)
                  AND (p_ref IS NULL OR base.option_ref = p_ref)
                  AND (p_file IS NULL OR a.pk_file = p_file)
                  AND (p_book IS NULL OR CALL.book IN (SELECT pk_book
                                                         FROM t_book
                                                        WHERE lbl = p_book))
                  AND (   p_cty IS NULL
                       OR CALL.counterparty IN (SELECT pk_counterparty
                                                  FROM t_counterparty
                                                 WHERE lbl = p_cty)
                      )
                  AND CALL.alert_date = p_date1;
         END;
      ELSIF (p_date = '<')
      THEN
         BEGIN
            OPEN cur FOR
               SELECT *
                 FROM t_alerts a, t_alert_base base, t_alert_call CALL
                WHERE a.pk_alert = base.pk_alert
                  AND CALL.pk_option = base.pk_option
                  AND (p_obj IS NULL OR CALL.option_object = p_obj)
                  AND (p_prd IS NULL OR CALL.product = p_prd)
                  AND (p_ref IS NULL OR base.option_ref = p_ref)
                  AND (p_file IS NULL OR a.pk_file = p_file)
                  AND (p_book IS NULL OR CALL.book IN (SELECT pk_book
                                                         FROM t_book
                                                        WHERE lbl = p_book))
                  AND (   p_cty IS NULL
                       OR CALL.counterparty IN (SELECT pk_counterparty
                                                  FROM t_counterparty
                                                 WHERE lbl = p_cty)
                      )
                  AND CALL.alert_date < p_date1;
         END;
      ELSIF (p_date = '>')
      THEN
         BEGIN
            OPEN cur FOR
               SELECT *
                 FROM t_alerts a, t_alert_base base, t_alert_call CALL
                WHERE a.pk_alert = base.pk_alert
                  AND CALL.pk_option = base.pk_option
                  AND (p_obj IS NULL OR CALL.option_object = p_obj)
                  AND (p_prd IS NULL OR CALL.product = p_prd)
                  AND (p_ref IS NULL OR base.option_ref = p_ref)
                  AND (p_file IS NULL OR a.pk_file = p_file)
                  AND (p_book IS NULL OR CALL.book IN (SELECT pk_book
                                                         FROM t_book
                                                        WHERE lbl = p_book))
                  AND (   p_cty IS NULL
                       OR CALL.counterparty IN (SELECT pk_counterparty
                                                  FROM t_counterparty
                                                 WHERE lbl = p_cty)
                      )
                  AND CALL.alert_date > p_date1;
         END;
      ELSIF (p_date = 'Between')
      THEN
         BEGIN
            OPEN cur FOR
               SELECT *
                 FROM t_alerts a, t_alert_base base, t_alert_call CALL
                WHERE a.pk_alert = base.pk_alert
                  AND CALL.pk_option = base.pk_option
                  AND (p_obj IS NULL OR CALL.option_object = p_obj)
                  AND (p_prd IS NULL OR CALL.product = p_prd)
                  AND (p_ref IS NULL OR base.option_ref = p_ref)
                  AND (p_file IS NULL OR a.pk_file = p_file)
                  AND (p_book IS NULL OR CALL.book IN (SELECT pk_book
                                                         FROM t_book
                                                        WHERE lbl = p_book))
                  AND (   p_cty IS NULL
                       OR CALL.counterparty IN (SELECT pk_counterparty
                                                  FROM t_counterparty
                                                 WHERE lbl = p_cty)
                      )
                  AND CALL.alert_date > p_date1
                  AND CALL.alert_date < p_date2;
         END;
      END IF;
si on regarde bien, dans chaque bloc, une partie est commune
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
OPEN cur FOR
               SELECT *
                 FROM t_alerts a, t_alert_base base, t_alert_call CALL
                WHERE a.pk_alert = base.pk_alert
                  AND CALL.pk_option = base.pk_option
                  AND (p_obj IS NULL OR CALL.option_object = p_obj)
                  AND (p_prd IS NULL OR CALL.product = p_prd)
                  AND (p_ref IS NULL OR base.option_ref = p_ref)
                  AND (p_file IS NULL OR a.pk_file = p_file)
                  AND (p_book IS NULL OR CALL.book IN (SELECT pk_book
                                                         FROM t_book
                                                        WHERE lbl = p_book))
                  AND (   p_cty IS NULL
                       OR CALL.counterparty IN (SELECT pk_counterparty
                                                  FROM t_counterparty
                                                 WHERE lbl = p_cty)
                      )
j'aimerai trouver un moyen "factoriser" tout cela. par exemple en mettant cette partie commune dans une table temporaire puis ensuite faire une select sur cette table selon les autres filtres (if, etc).

l'avantage: meilleure visibilité, et surtout un seul bloc de code à maintenir.

peut-être surtout que cela m'aidera à trouver l'origine de l'erreur "ORA-24338: statement handle not executed". je suppose que ca vient des cursor imbriqués dans un bloc IF mais je vois pas comment faire dedans.

merci d'avance à celui(ceux) qui pourra(ont) m'éclairer.
__________________
moi c'est Louis-Guillaume, ni Louis, ni Guillaume mais Louis-Guillaume et je n'aide pas ceux qui écorchent mon nom
Louis-Guillaume Morand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 15h18   #2
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
pourquoi pas une vue sur :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
              SELECT *
                 FROM t_alerts a, t_alert_base base, t_alert_call CALL
                WHERE a.pk_alert = base.pk_alert
                  AND CALL.pk_option = base.pk_option
                  AND (p_obj IS NULL OR CALL.option_object = p_obj)
                  AND (p_prd IS NULL OR CALL.product = p_prd)
                  AND (p_ref IS NULL OR base.option_ref = p_ref)
                  AND (p_file IS NULL OR a.pk_file = p_file)
                  AND (p_book IS NULL OR CALL.book IN (SELECT pk_book
                                                         FROM t_book
                                                        WHERE lbl = p_book))
                  AND (   p_cty IS NULL
                       OR CALL.counterparty IN (SELECT pk_counterparty
                                                  FROM t_counterparty
                                                 WHERE lbl = p_cty)
                      );
Sinon, un truc de ce style :
Code :
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
stmt := '               SELECT * ' ||
        '         FROM t_alerts a, t_alert_base base, t_alert_call CALL ' ||
        '        WHERE a.pk_alert = base.pk_alert ' ||
        '          AND CALL.pk_option = base.pk_option ' ||
        '          AND (p_obj IS NULL OR CALL.option_object = p_obj) ' ||
        '          AND (p_prd IS NULL OR CALL.product = p_prd) ' ||
        '          AND (p_ref IS NULL OR base.option_ref = p_ref) ' ||
        '          AND (p_file IS NULL OR a.pk_file = p_file) ' ||
        '          AND (p_book IS NULL OR CALL.book IN (SELECT pk_book ' ||
        '                                                 FROM t_book ' ||
        '                                                WHERE lbl = p_book)) ' ||
        '          AND (   p_cty IS NULL ' ||
        '               OR CALL.counterparty IN (SELECT pk_counterparty ' ||
        '                                          FROM t_counterparty ' ||
        '                                         WHERE lbl = p_cty) ' ||
        '              ) ';
 
IF (p_date = 'Between')
THEN
	  stmt := stmt || '  AND CALL.alert_date > p_date1 AND CALL.alert_date < p_date2');
ELSIF (p_date IS NOT NULL)
	  stmt := stmt || ' AND CALL.alert_date ' || p_date || ' p_date1';
END IF;
 
FOR i IN stmt LOOP ...
ORA-24338 tu ouvres un curseur qui n'existe pas... c'est plutôt FOR...LOOP que tu dois faire je pense.
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 15h30   #3
Rédacteur

 
Avatar de Louis-Guillaume Morand
 
Homme Louis-Guillaume MORAND
Consultant @ Microsoft
Inscription : mars 2003
Messages : 10 713
Détails du profil
Informations personnelles :
Nom : Homme Louis-Guillaume MORAND
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant @ Microsoft
Secteur : Conseil

Informations forums :
Inscription : mars 2003
Messages : 10 713
Points : 15 946
Points : 15 946
pour la vue...bah je sais pas faire

pour ta solution du statement que tu construis, j'y ai pensé mais justement, je vois pas trop la fin après
Citation:
FOR i IN stmt LOOP ...

en fait, en oracle (et j'aime pas pour ca), pour l'interroger depuis du .Net, tu dois passer un curseur vide, et faire "open cur for select" et ca se retourne tout seul.
pour l'erreur que tu cites, justement je ne la comprend pas, je n'ai jamais eu besoin de créer le curseur. dans des centaines d'autres sp, ca marche directement.

venant du tsql, le plsql me perd un peu dans sa logique là :/
Il faudrait que j'arrive à remplir mon cursor depuis mon statement.

la solution de la vue facilement la lecture du code mais j'aurais tjs mon erreur et la deuxieme solution me semble pas mal mais je vois pas comment l'utiliser :'(
__________________
moi c'est Louis-Guillaume, ni Louis, ni Guillaume mais Louis-Guillaume et je n'aide pas ceux qui écorchent mon nom
Louis-Guillaume Morand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 15h34   #4
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Citation:
Envoyé par Louis-Guillaume Morand Voir le message
pour la vue...bah je sais pas faire
Rien de plus simple :

Code :
CREATE VIEW tavue AS [ta requête];
Citation:
Envoyé par Louis-Guillaume Morand Voir le message
pour ta solution du statement que tu construis, j'y ai pensé mais justement, je vois pas trop la fin après
j'comprends pas ?

Citation:
Envoyé par Louis-Guillaume Morand Voir le message
en fait, en oracle (et j'aime pas pour ca), pour l'interroger depuis du .Net, tu dois passer un curseur vide, et faire "open cur for select" et ca se retourne tout seul.
pour l'erreur que tu cites, justement je ne la comprend pas, je n'ai jamais eu besoin de créer le curseur. dans des centaines d'autres sp, ca marche directement.
c'est un code .Net que tu donnes là ?

Citation:
Envoyé par Louis-Guillaume Morand Voir le message
la solution de la vue facilement la lecture du code mais j'aurais tjs mon erreur et la deuxieme solution me semble pas mal mais je vois pas comment l'utiliser :'(
Code :
OPEN CURSOR cur FOR stmt
non ?
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 15h40   #5
Rédacteur

 
Avatar de Louis-Guillaume Morand
 
Homme Louis-Guillaume MORAND
Consultant @ Microsoft
Inscription : mars 2003
Messages : 10 713
Détails du profil
Informations personnelles :
Nom : Homme Louis-Guillaume MORAND
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant @ Microsoft
Secteur : Conseil

Informations forums :
Inscription : mars 2003
Messages : 10 713
Points : 15 946
Points : 15 946
Code :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
   PROCEDURE sp_basicsearch (
      cur       OUT      sys_refcursor,
      p_book    IN       NVARCHAR2,
      p_cty     IN       NVARCHAR2,
      p_obj     IN       NVARCHAR2,
      p_prd     IN       NVARCHAR2,
      p_ref     IN       NVARCHAR2,
      p_file    IN       NUMBER,
      p_date    IN       NVARCHAR2,
      p_date1   IN       DATE DEFAULT sysdate,
     p_date2   IN       DATE DEFAULT sysdate
   )
   IS
 
	  stmt NVARCHAR2(500);
   BEGIN
 
     stmt := '               SELECT * ' ||
        '         FROM t_alerts a, t_alert_base base, t_alert_call CALL ' ||
        '        WHERE a.pk_alert = base.pk_alert ' ||
        '          AND CALL.pk_option = base.pk_option ' ||
        '          AND (p_obj IS NULL OR CALL.option_object = p_obj) ' ||
        '          AND (p_prd IS NULL OR CALL.product = p_prd) ' ||
        '          AND (p_ref IS NULL OR base.option_ref = p_ref) ' ||
        '          AND (p_file IS NULL OR a.pk_file = p_file) ' ||
        '          AND (p_book IS NULL OR CALL.book IN (SELECT pk_book ' ||
        '                                                 FROM t_book ' ||
        '                                                WHERE lbl = p_book)) ' ||
        '          AND (   p_cty IS NULL ' ||
        '               OR CALL.counterparty IN (SELECT pk_counterparty ' ||
        '                                          FROM t_counterparty ' ||
        '                                         WHERE lbl = p_cty) ' ||
        '              ) ';
 
		IF (p_date = 'Between')
		THEN
			  stmt := stmt || '  AND CALL.alert_date > p_date1 AND CALL.alert_date < p_date2';
 
		ELSIF (p_date IS NOT NULL)
			  stmt := stmt || ' AND CALL.alert_date ' || p_date || ' p_date1';
		END IF;
 
	    open cur FOR stmt;
   END;
END pkg_reports;
/
plusieurs choses (mais on approche ^^)

au spell il aime pas cette ligne
Code :
1
2
ELSIF (p_date IS NOT NULL)
			  stmt := stmt || ' AND CALL.alert_date ' || p_date || ' p_date1';
=>
Citation:
(S92) Expecting: ! != (+) * ** + - / < <= <> || = = > >= ^ ^= AND AT BETWEEN DAY IN IS LIKE LIKE2 LIKE4 LIKEC MOD NOT OR REM THEN YEAR
edit: en fait c'est le THEN qui manque


à la compilation, il aime pas celle là
=>
Citation:
PLS-00382: expression is of wrong type

j'ai trouvé un open...for execute
http://www.redhat.com/docs/manuals/d...l-cursors.html
mais oracle n'en veut pas car ca semble être pour postgres uniquement
__________________
moi c'est Louis-Guillaume, ni Louis, ni Guillaume mais Louis-Guillaume et je n'aide pas ceux qui écorchent mon nom
Louis-Guillaume Morand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 16h04   #6
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 319
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 319
Points : 5 837
Points : 5 837
Coller le paramètres de la procédure dans la requête comme c'est proposé ne marchéra pas!
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 16h07   #7
Rédacteur

 
Avatar de Louis-Guillaume Morand
 
Homme Louis-Guillaume MORAND
Consultant @ Microsoft
Inscription : mars 2003
Messages : 10 713
Détails du profil
Informations personnelles :
Nom : Homme Louis-Guillaume MORAND
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant @ Microsoft
Secteur : Conseil

Informations forums :
Inscription : mars 2003
Messages : 10 713
Points : 15 946
Points : 15 946
Citation:
Envoyé par mnitu Voir le message
Coller le paramètres de la procédure dans la requête comme c'est proposé ne marchéra pas!
tu peux être plus précis? tu parles de "p_date"? puisqu'on construit une chaine de caractère et qu'on l'execute, je ne vois pas de raison que cela ne marche pas, non?

d'ailleurs, je viens de trouver un probleme que j'ai corrigé
si je fais
Code :
1
2
stmt NVARCHAR2(500)
open cur FOR stmt;
il aime pas du tout
mais si je fais
Code :
1
2
stmt VARCHAR2(500)
open cur FOR stmt;
ca marche.


Maintenant c'est à l'execution que j'ai une erreur, il te semble plus comprendre et trouver les objet paramètres

p_book : invalid identifier (idem pour les autres)
__________________
moi c'est Louis-Guillaume, ni Louis, ni Guillaume mais Louis-Guillaume et je n'aide pas ceux qui écorchent mon nom
Louis-Guillaume Morand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 16h37   #8
Rédacteur

 
Avatar de Louis-Guillaume Morand
 
Homme Louis-Guillaume MORAND
Consultant @ Microsoft
Inscription : mars 2003
Messages : 10 713
Détails du profil
Informations personnelles :
Nom : Homme Louis-Guillaume MORAND
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant @ Microsoft
Secteur : Conseil

Informations forums :
Inscription : mars 2003
Messages : 10 713
Points : 15 946
Points : 15 946
TADAAAAAAAAAAAAAAAAAAAAAAAAAAAAM

je suis venu ici pour simlpifier une requête et le resultat est
Code :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
CREATE OR REPLACE PACKAGE BODY pkg_reports
AS
   PROCEDURE sp_basicsearch (
      cur       OUT      sys_refcursor,
      p_book    IN       NVARCHAR2,
      p_cty     IN       NVARCHAR2,
      p_obj     IN       NVARCHAR2,
      p_prd     IN       NVARCHAR2,
      p_ref     IN       NVARCHAR2,
      p_file    IN       NUMBER,
      p_date    IN       NVARCHAR2,
      p_date1   IN       DATE DEFAULT SYSDATE,
      p_date2   IN       DATE DEFAULT SYSDATE
   )
   IS
      stmt   VARCHAR2 (5000);
   BEGIN
      stmt :='SELECT base.pk_option '
         || 'FROM t_alerts a, t_alert_base base, t_alert_call CALL '
         || 'WHERE a.pk_alert = base.pk_alert '
         || 'AND CALL.pk_option = base.pk_option ';
 
 
      IF (p_obj IS NOT NULL)
      THEN
         stmt := stmt || '  AND CALL.option_object = '' ' || p_obj || ' ''';
      END IF;
 
      IF (p_prd IS NOT NULL)
      THEN
         stmt := stmt || '  AND CALL.product = '' ' || p_prd || ' '' ';
      END IF;
 
      IF (p_ref IS NOT NULL)
      THEN
         stmt := stmt || '  AND base.option_ref ='' ' || p_ref || ' '' ';
      END IF;
 
	  IF (p_file IS NOT NULL)
      THEN
         stmt := stmt || '  AND a.pk_file ='' ' || p_file || ' '' ';
      END IF;
 
      IF (p_book IS NOT NULL)
      THEN
         stmt :=
               stmt
            || '  AND CALL.book IN (SELECT pk_book FROM t_book WHERE lbl = '' '
            || p_book
            || ' '' )';
      END IF;
 
      IF (p_cty IS NOT NULL)
      THEN
         stmt :=
               stmt
            || '  AND CALL.counterparty IN (SELECT pk_counterparty FROM t_counterparty WHERE lbl = '' '
            || p_cty
            || ' '' ) ';
      END IF;
 
      IF (p_date = 'Between')
      THEN
         stmt := stmt
            || '  AND CALL.alert_date > p_date1 AND CALL.alert_date < p_date2';
      ELSIF (p_date IS NOT NULL)
      THEN
         stmt := stmt || ' AND CALL.alert_date ' || p_date || ' p_date1';
      END IF;
 
 
      OPEN cur FOR stmt;
   END;
END pkg_reports;
/
ca compile nickel mais par contre, ca marche pas super bien :/
__________________
moi c'est Louis-Guillaume, ni Louis, ni Guillaume mais Louis-Guillaume et je n'aide pas ceux qui écorchent mon nom
Louis-Guillaume Morand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 16h55   #9
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 319
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 319
Points : 5 837
Points : 5 837
Comme c’est écrit maintenant la procédure pose 2 grands soucis liés à la non-utilisation des variables de liaison :
  • Chaque requête générée par l’appel à la procédure risque d’être unique et nécessite le « hard parsing »
  • La procédure présente une faille de sécurité majore (google sql injection)

Essaye d'afficher la requête que t'a construit pour voir pour quoi ça ne marche pas.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 16h57   #10
Rédacteur

 
Avatar de Louis-Guillaume Morand
 
Homme Louis-Guillaume MORAND
Consultant @ Microsoft
Inscription : mars 2003
Messages : 10 713
Détails du profil
Informations personnelles :
Nom : Homme Louis-Guillaume MORAND
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant @ Microsoft
Secteur : Conseil

Informations forums :
Inscription : mars 2003
Messages : 10 713
Points : 15 946
Points : 15 946
effectivement, la construction c'est bien mais j'arrive pas à la créer comme j'ai voulu.
j'ai alors tout jeté et recommencé de zéro pas à pas.
j'ai finalement trouvé une solution plus propre et facile à debugguer
Code :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
CREATE OR REPLACE PACKAGE BODY pkg_reports
AS
   PROCEDURE sp_basicsearch (
      cur       OUT      sys_refcursor,
      p_book    IN       NVARCHAR2,
      p_cty     IN       NVARCHAR2,
      p_obj     IN       NVARCHAR2,
      p_prd     IN       NVARCHAR2,
      p_ref     IN       NVARCHAR2,
      p_file    IN       NUMBER,
      p_date    IN       NVARCHAR2,
      p_date1   IN       DATE DEFAULT SYSDATE,
      p_date2   IN       DATE DEFAULT SYSDATE
   )
   IS
   BEGIN
      OPEN cur FOR
         SELECT base.pk_option
           FROM t_alerts a, t_alert_base base, t_alert_call CALL
          WHERE a.pk_alert = base.pk_alert
            AND CALL.pk_option = base.pk_option
            AND (p_obj IS NULL OR CALL.option_object = p_obj)
            AND (p_prd IS NULL OR CALL.product = p_prd)
            AND (p_ref IS NULL OR base.option_ref = p_ref)
            AND (p_file IS NULL OR a.pk_file = p_file)
            AND (p_book IS NULL OR CALL.book IN (SELECT pk_book
                                                   FROM t_book
                                                  WHERE lbl = p_book))
            AND (p_cty IS NULL
                 OR CALL.counterparty IN (SELECT pk_counterparty
                                            FROM t_counterparty
                                           WHERE lbl = p_cty)
                )
            AND (   (p_date = '=' AND to_date(CALL.alert_date, 'dd/mm/yyyy')= p_date1)
                 OR (p_date = '<' AND CALL.alert_date < p_date1)
                 OR (p_date = '>' AND CALL.alert_date > p_date1)
                 OR (    p_date = 'between'
                     AND (    CALL.alert_date > p_date1
                          AND CALL.alert_date < p_date2
                         )
                    )
                 OR (p_date IS NULL)
                );
   END;
END pkg_reports;
/
merci à vous deux
__________________
moi c'est Louis-Guillaume, ni Louis, ni Guillaume mais Louis-Guillaume et je n'aide pas ceux qui écorchent mon nom
Louis-Guillaume Morand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 17h00   #11
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 453
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 453
Points : 4 215
Points : 4 215
1/ C'est quoi ces espaces ?
Code :
a.pk_file ='' ' || p_file || ' ''
avec un execute immediate, quand on n'est pas sur : Toujours faire un DBMS_OUTPUT.PUT_LINE de la chaine à exécuter (attention dbms_output est limité à 256 cars)

A mon avis c'est
Code :
a.pk_file =''' || p_file || '''

2/ BETWEEN inclue les bornes donc
Code :
1
2
3
4
IF (p_date = 'Between')
      THEN
         stmt := stmt
            || '  AND CALL.alert_date > p_date1 AND CALL.alert_date < p_date2';
devrait être remplacé par
Code :
'  AND CALL.alert_date BETWEEN p_date1 AND p_date2'
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 19h48   #12
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Citation:
Envoyé par Louis-Guillaume Morand Voir le message
j'ai finalement trouvé une solution plus propre et facile à debugguer
mais malheureusement probablement moins performante
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2008, 19h49   #13
Rédacteur

 
Avatar de Louis-Guillaume Morand
 
Homme Louis-Guillaume MORAND
Consultant @ Microsoft
Inscription : mars 2003
Messages : 10 713
Détails du profil
Informations personnelles :
Nom : Homme Louis-Guillaume MORAND
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant @ Microsoft
Secteur : Conseil

Informations forums :
Inscription : mars 2003
Messages : 10 713
Points : 15 946
Points : 15 946
Citation:
Envoyé par orafrance Voir le message
mais malheureusement probablement moins performante
pourquoi?
je veux dire, par rapport à la construction d'une query-string et son execution. où se situe la perte? ca m'intéresse
__________________
moi c'est Louis-Guillaume, ni Louis, ni Guillaume mais Louis-Guillaume et je n'aide pas ceux qui écorchent mon nom
Louis-Guillaume Morand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/02/2008, 14h28   #14
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Code :
1
2
SELECT ...
WHERE col1 = toto OR col1 > toto
peut être équivalent à
Code :
1
2
3
4
5
SELECT ...
WHERE col1 = toto 
UNION ALL 
SELECT ...
WHERE col1 > toto
Soit 2 requêtes au lieu d'une seule
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/02/2008, 14h33   #15
Rédacteur

 
Avatar de Louis-Guillaume Morand
 
Homme Louis-Guillaume MORAND
Consultant @ Microsoft
Inscription : mars 2003
Messages : 10 713
Détails du profil
Informations personnelles :
Nom : Homme Louis-Guillaume MORAND
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant @ Microsoft
Secteur : Conseil

Informations forums :
Inscription : mars 2003
Messages : 10 713
Points : 15 946
Points : 15 946
bah non :/

moi je fais pas du tout
Citation:
SELECT ...
WHERE col1 = toto OR col1 > toto
enfin si mais c'est un ou exclusif donc ton union me retounerait les col >=toto si je comprend bien. non?
__________________
moi c'est Louis-Guillaume, ni Louis, ni Guillaume mais Louis-Guillaume et je n'aide pas ceux qui écorchent mon nom
Louis-Guillaume Morand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/02/2008, 14h43   #16
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Citation:
Envoyé par Louis-Guillaume Morand Voir le message
enfin si mais c'est un ou exclusif
OR = UNION ALL, le parseur réécrit la requête comme ça... et même si une seul requête des UNION retourne des infos, il faut bien qu'Oracle les exécute toute, lui il n'en sait rien que c'est exclusif
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/02/2008, 16h55   #17
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 319
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 319
Points : 5 837
Points : 5 837
Citation:
Envoyé par orafrance Voir le message
OR = UNION ALL, le parseur réécrit la requête comme ça... et même si une seul requête des UNION retourne des infos, il faut bien qu'Oracle les exécute toute, lui il n'en sait rien que c'est exclusif
J'ai des gros doutes que cela ce passe comme ça. Peut tu la démontrer ?
La solution qu'il propose est correcte dans son cas le SQL statique c’est mieux que le SQL dynamique.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2008, 09h31   #18
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Il me semble qu'on le voit dans l'explain plan mais ça a peut-être changé avec les nouvelles versions... j'avoue que je n'ai pas vérifié
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2008, 10h21   #19
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 319
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 319
Points : 5 837
Points : 5 837
Bref, parfois il le fait parfois il ne le fait pas: How the CBO Transforms ORs into Compound Queries
Dans ce cas je ne pense pas qu'il le fait.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2008, 11h16   #20
Membre éprouvé
 
Inscription : décembre 2007
Messages : 354
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 354
Points : 408
Points : 408
Citation:
Envoyé par mnitu Voir le message
Bref, parfois il le fait parfois il ne le fait pas: How the CBO Transforms ORs into Compound Queries
Dans ce cas je ne pense pas qu'il le fait.
Il peut aussi utiliser dans certains cas une transformation en index bitmap!
__________________
Consultant et formateur Oracle
Michel SALAIS est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 08h10.


 
 
 
 
Partenaires

Hébergement Web