Bonjour a tous,

Je suis sur une architecture multiple et je dois créer une procédure de centralisation de données (pour reporting).

DB1, Oracle 10.1
||
|| (db link)
V
DB2, Oracle 9.2
|| || ...
V V
DB3a, Oracle 9.2 | DB3b, Oracle 9.2 ...

Une procédure de DB1 fait appel a n fonctions sur DB2. Chacune de ces fonctions effectuent un select sur une DB3, travail le résultat et renvoie le résultat.

Les appels de fonction se font via
Code : Sélectionner tout - Visualiser dans une fenêtre à part
SELECT mafonction@db2 INTO maVariable FROM dual;
Chaque fonction ressemble a cela:
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
CREATE OR REPLACE FUNCTION F_MA_FONCTION return varchar2    
IS
 
    CURSOR diff IS
        SELECT 
            f1.champ1, 
            f2.champ2
        FROM 
            table_locale f1 FULL OUTER JOIN table_distante@DB3n f2 ON f1.id = f2.id 
        WHERE 
            condition(f1, f2);
 
    -- Variables
    w_message       VARCHAR2(32767);
 
BEGIN
 
    -- Initilisation des variables
    w_message:='entête informative';
 
    FOR current IN diff LOOP
      w_message:=w_message||' infos structurées sur les resultats';
    END LOOP;
 
    return w_message;
EXCEPTION
    WHEN OTHERS THEN
        w_message := 'SQL ERROR: '||SQLERRM;
        return w_message;
END;
/
Tout vas bien dans le meilleur des mondes ... ou pas

La limite du nombre de dblink ouvert sur la base DB2 est de 4. Dés que la procédure appelle la 5eme fonction (appelant elle-même une 5eme base DB3e), je récupère une erreure de DB2 me disant que le nombre maximum de dbLink est ouvert. Pourtant, les fonctions sont appelées séquentiellement.

J'ai tenté de placer un commit avant le return des fonction mais cela ne semble pas autorisé par Oracle. Dans la procédure, je comit après chaque appel de fonction mais cela ne change rien.

Après des recherches sur internet, il semblerais que la session ouverte sur DB2 par la procédure soit persistante et que tant qu'elle n'est pas fermée, les dblink ouverts le restent, bloquant (inutilement) une place.

D'ou ma question, comment puis-je fermer ma session entre chaque appel a une fonction depuis ma procédure?
S'il y a une technique plus simple ou plus propre, quelle est-elle?

Merci d'avance.

Cordialement.