Bonjour,
J'ai une requete Oracle qui fonctionne comme je le souhaite et avec des temps de réponses de l'ordre de la seconde. Pas de problème de ce coté la.
Maintenant cette requete est utilisée dans du Pro*C et c'est la que ça se gate. La requete met alors une dizaine de minutes à retourner un résultat qui est de plus faux (pas le bon nombre de lignes).
Je sais que la requete est correcte d'un point de vue Oracle vu que je l'ai testée unitairement.
Je sais que le Pro*C utilisant le retour de la requete est correct vu que j'ai testé en remplaçant la requete par un select * from table en ayant remplit "table" avec le résultat de ma requête.
J'ai testé différentes solution :
- Requete dynamique (code ci-dessous)
- Utilisation d'une vue (avec et sans requete dynamique)
Avec le même résultat.
Je n'ai pas pu tester une vue matérialisée car cela pose d'autres soucis.
Ma question est donc de savoir pourquoi on observe ce comportement ?
Est-ce corrigeable et si oui comment ?
J'aimerai éviter la solution de remplir une table avec le résultat de ma requete avant le traitement.
Voici la requete banalisée :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 WITH TGN AS ( SELECT TGN_STR, min(path) keep(dense_rank last ORDER BY l) path, max(l) l FROM ( SELECT TGN_STR, level l, SYS_CONNECT_BY_PATH(TGN_STR, '|') path FROM TABLE_TGN_STR connect BY prior TGN_STR=TGN_STR_PERE ) GROUP BY TGN_STR ) SELECT count(*) FROM ( SELECT CHAMP_STR1 CHAMP_STR1, DECODE(CHAMP_FLAG, 'E', 0, 1) CHAMP_FLAG, 100-10*(decode(instr(TGN1.path, act.TGA),0,0,instr(TGN1.path, act.TGA)-2))/4 + 1000-100*(decode(instr(TGN2.path, act.TGB),0,0,instr(TGN2.path,act.TGB)-2))/4 + 1000*tgn1.l + 10000*tgn2.l + DECODE(INFO, NULL, 4, 0) + DECODE(act.C1, NULL, 3, DECODE(act.C2, NULL, 2, DECODE(act.C3, NULL, 1, 0)) ) CHAMP_NUM1, TRIM(RPAD(act.C6, 4)|| act.C5|| RPAD(tgn1.TGN_STR, 3)|| RPAD(tgn2.TGN_STR, 3)|| RPAD(NVL(act.C1, ' '), 5)|| RPAD(NVL(act.C2, ' '), 5)|| RPAD(NVL(act.C3, ' '), 5)|| RPAD(NVL(act.C4, ' '), 5) ) CHAMP_STR3, DECODE(INFO, NULL, 1, 0) CHAMP_NUM2, CHAMP_STR4 CHAMP_STR4, TO_CHAR(DATE_DEBUT, 'YYYYMMDDHH24MISS') date_debut_str, DATE_DEBUT date_debut, TO_CHAR(DATE_FIN, 'YYYYMMDDHH24MISS') date_fin_str, DATE_FIN date_fin FROM TABLE_ACT ACT JOIN TGN TGN1 ON instr(TGN1.path, act.TGA) > 0 JOIN TGN TGN2 ON instr(TGN2.path, act.TGB) > 0 );
Et voici le code Pro*C en version requete dynamique ( obligatoire vu la requete, le Pro*C ne compilant pas sinon )
Note : ici j'ai mis un count(*) dans la requete pour simplifier et voir le nombre de ligne retournées. Nombre qui est donc différent de la même requete executée directement sous SQL Dev par exemple.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 VARCHAR dyn_requete[4000]; long Nombre; strcpy(dyn_requete.arr, "requete ci-dessus"); dyn_requete.len = strlen(dyn_requete.arr); EXEC SQL CONTEXT USE :g_OracleContext; EXEC SQL PREPARE ReqCount FROM :dyn_requete; EXEC SQL DECLARE Cursor CURSOR FOR ReqCount; EXEC SQL OPEN Cursor; /* gestion d'erreur */ EXEC SQL FETCH Cursor INTO :Nombre; EXEC SQL CLOSE Cursor;
Le : g_OracleContext est bien défini.
Merci pour vos réponses/pistes
(Note bis: ce post est un doublon d'un autre que je passe en delestage, le précédent n'étant pas assez clair et mal positionné dans le forum)
Partager