Créer un Dblink vers une base d’une ancienne version

L’utilisation de Dblink est souvent décriée. Cependant, cela reste l’accès le plus direct aux données d’une autre base en temps réel.

Lorsque l’on upgrade une base ou lors d’un nouveau projet, on peut être confronté à des problèmes de compatibilité concernant ses Dblink vers des versions de bases plus anciennes.

Cela se caractérise par le message d’erreur suivant :

ORA-03134: Connections to this server version are no longer supported.

 

Compatibilité des Dblinks

La compatibilité des Dblinks suit celle des Clients/BDD et peut être vérifiée depuis la doc Oracle suivante :

Doc ID 207303.1 : Client/Server Interoperability Support Matrix for Different Oracle Versions

Dans la matrice de compatibilité, il faut alors considérer « Client Version » comme la version de la base qui contient le Dblink et « Server Version » comme celle de la base ciblée par le Dblink.

 

Solution de contournement

La première solution qui semblerait évidente serait l’upgrade de la base source. Cependant, une base reste rarement dans une version ancienne et non supportée sans raisons. Il peut, par exemple, s’agir d’une base supportant une application ancienne qui ne peut être migrée ou dont l’effort de migration ne se justifie pas.

Dans ce cas, il existe une solution de contournement qui permet de ne pas s’obliger à upgrader la base source. Cette solution consiste à mettre en place une base intermédiaire dans une version accessible par la base contenant le Dblink et étant capable d’accéder à la base pointée par le Dblink.

Un « chaînage » de Dblink permet alors d’accéder aux données de la base dans une version non supportée par l’intermédiaire d’une autre base.

Exemple : Base contenant le Dblink (19c ou 18c) > Base intermédiaire (11gR2) > Base ciblée par le Dblink (10g ou 9i)

 

Mise en place

Selon l’exemple ci-dessus, il faudra alors modifier le Dblink (ou seulement l’alias tns du fichier tnsname.ora correspondant au moteur 19c) pour qu’il pointe vers la base intermédiaire au lieu de la base cible. Si l’on ne souhaite pas modifier le code PL/SQL utilisant le Dblink, on peut faire le choix de ne pas modifier le nom du Dblink.

Sur la base intermédiaire (la 11gR2 dans l’exemple), on créera alors un Dblink vers la base cible (ici en 10g).

 

Accès aux objets

 

Tables, vues ou vues matérialisées :

L’accès aux tables, vues ou vues matérialisées de la base cible (ici en 10g) par la base contenant le Dblink (19c) peut se faire via des synonymes incluant le Dblink qui seront créés sur la base intermédiaire (11g). Cependant on préfèrera créer des vues plutôt que des synonymes :

CREATE VIEW user.object AS SELECT * FROM user.object@dblink_vers_ancienne_base;

Ainsi, sur la base 19c, l’accès à l’objet se fera strictement de la même manière (Via le Dblink entre la base 19c et la base intermédiaire). Il ne sera donc pas nécessaire de réécrire le code applicatif et/ou le code PL/SQL.

 

Fonctions, procédures, packages :

Les choses se compliquent un peu quand il s’agit de fonctions ou procédures. Le chainage de Dblink seul ne permet pas d’exécuter du code PL/SQL sur la base distante (10g) depuis la base 19c.

La solution consiste donc à créer une procédure sur la base intermédiaire qui sera appelée par la base 19c via le Dblink et qui appellera la procédure ou fonction sur la base 10g via le second Dblink :

CREATE PROCEDURE owner.nom_procedure ( Param1 IN VARCHAR2, Param2 IN NUMBER) AS
BEGIN
owner.nom_procedure@dblink_vers_ancienne_base (Param1, Param2);
END;

Si l’on conserve le même nom de propriétaire et d’objet sur la base intermédiaire, cela permet une fois de plus de ne pas avoir à modifier le code applicatif et/ou PL/SQL sur la base 19c.

 

Séquences :

Abordons maintenant un cas un peu plus compliqué encore, celui de l’utilisation d’une séquence de la base distante.

La création d’un synonyme sur la base intermédiaire ne permet pas d’utiliser la séquence correctement. Le moteur 19c remonte le chaînage Dblink et avoue son incapacité à l’utiliser (avec le même message d’erreur).

L’astuce consiste donc à créer une fonction sur la base intermédiaire qui appelle la séquence sur la base ciblée par le Dblink :

CREATE FUNCTION fonction_sequence
RETURN NUMBER IS
retour NUMBER;
BEGIN
SELECT owner.nom_sequence.nextval@dblink_vers_ancienne_base INTO retour FROM DUAL;
RETURN (retour);
END;

Dans ce cas-ci seulement, l’appel de la séquence distante doit être modifiée dans le code applicatif et/ou le code PL/SQL.
Même si cela est un peu plus contraignant, cela reste un moindre mal permettant de s’affranchir d’une migration imprévue et potentiellement délicate.

Ainsi on remplacera un appel à la séquence du type :

SELECT owner.nom_sequence.NextVal@dblink_initial INTO variable FROM DUAL;
par
SELECT owner.fonction_sequence@dblink_vers_base_intermediaire INTO variable FROM DUAL;

 

Enfin, si vous souhaitez analyser l’effort que constituerait la migration d’une base contenant des Dblinks vers une base d’une version ancienne, je vous invite à lire (ou relire) un précédant article qui traitait de la détection de l’utilisation des Dblinks.

 
Et si vous souhaitez vous former sur Oracle Database, découvrez notre offre de formations officielles Oracle.