IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Apprendre comment interroger une base MariaDB depuis Oracle
Un billet blog de CinePhil

Le , par CinePhil

0PARTAGES

On trouve différents tutoriels, la plupart en anglais, au sujet de la création d'un database_link dans Oracle pour accéder à une base MySQL. L'un parle du cas spécifique de l'accès à une base MariaDB mais ses exemples de code m'ont posé quelques soucis de compréhension entraînant par la suite un refus de fonctionnement et quelques prises de tête pendant pas mal de temps.
Je vais donc décrire ici pas à pas ce qu'il faut faire pour que ça fonctionne.

Nota :
Pour les configurations ci-après, je me suis servi de mes fichiers de configuration réels que j'ai ensuite annonymisés. Si vous rencontrez des erreurs, n'hésitez pas à m'en faire part en commentaire.

1. Environnement technique utilisé
D'un côté, un serveur Oracle 12.2.0.1 sous OracleLinux que j'appelerai ici "ora.mondomaine.fr" avec une base de données nommée "bd_oracle" et un schéma nommé "schemora". Peu importe si le schéma contient des tables ou pas dans le cadre de ce tutoriel.

De l'autre côté, un serveur MariaDB (sous OpenSuse mais peu importe) que j’appellerai ici "mdb.mondomaine.fr" avec une base de données nommée "bd_maria" et une table nommée "t_source" contenant quelques lignes. Peu importe la structure de la table ; ce n'est pas important dans le cadre de ce tutoriel.
L'utilisateur autorisé à se connecter à la table pour l'interroger sera 'useroracle'@'ora.mondomaine.fr' et son mot de passe "User_ORA" (parce que, évidemment, vous n'accédez pas à vos BDD en root, n'est-ce pas ? ).

Bien entendu, les deux serveurs sont aptes à communiquer l'un avec l'autre.

2. Installation du driver ODBC
On commence par installer, si ce n'est pas déjà fait, le driver "unixODBC" sur le serveur Oracle :
Code bash : Sélectionner tout
sudo yum install unixODBC unixODBC-devel -y

3. Installation du connecteur ODBC pour MariaDB
Sur le serveur Oracle, il faut installer le connecteur ODBC propre à MariaDB pour que Oracle puisse interroger la BDD MariaDB.

Nota :
Comme je suis sur un serveur sous Oracle Linux, j'ai d'abord essayé d'installer le connecteur ODBC pour MySQL fournit dans la distribution mais je n'ai pas réussi à accéder à MariaDB, malgré la compatibilité de principe existant entre MySQL et MariaDB.

Conformément aux instructions présentes sur le site de MariaDB, pour RedHat et CentOS (puisque Oracle Linux est un clone de RedHat), on télécharge le connecteur dans un répertoire créé pour l'occasion puis on l'installe :
Code bash : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
mkdir odbc_package 
cd odbc_package 
wget https://downloads.mariadb.com/Connectors/odbc/connector-odbc-3.1.7/mariadb-connector-odbc-3.1.7-ga-rhel7-x86_64.tar.gz 
tar -xvzf mariadb-connector-odbc-3.1.7-ga-rhel7-x86_64.tar.gz 
sudo install lib64/libmaodbc.so /usr/lib64/ 
sudo install -d /usr/lib64/mariadb/ 
sudo install -d /usr/lib64/mariadb/plugin/ 
sudo install lib64/mariadb/plugin/auth_gssapi_client.so /usr/lib64/mariadb/plugin/ 
sudo install lib64/mariadb/plugin/caching_sha2_password.so /usr/lib64/mariadb/plugin/ 
sudo install lib64/mariadb/plugin/client_ed25519.so /usr/lib64/mariadb/plugin/ 
sudo install lib64/mariadb/plugin/dialog.so /usr/lib64/mariadb/plugin/ 
sudo install lib64/mariadb/plugin/mysql_clear_password.so /usr/lib64/mariadb/plugin/ 
sudo install lib64/mariadb/plugin/sha256_password.so /usr/lib64/mariadb/plugin/

4. Création de la source de données
On peut suivre maintenant les instructions de la page "Creating a Data Source with MariaDB Connector/ODBC" pour configurer le driver unixODBC afin qu'il puisse communiquer avec MariaDB. Commençons par créer, avec l'éditeur de notre choix, un fichier "MariaDB_odbc_driver_template.ini" décrivant le connecteur ODBC de MariaDB et le chemin du fichier à utiliser pour le driver :
Code ini : Sélectionner tout
1
2
3
[MariaDB ODBC 3.0 Driver] 
Description = MariaDB Connector/ODBC v.3.0 
Driver = /usr/lib64/libmaodbc.so

Puis installons cette configuration dans le fichier de configuration de unixODBC : /etc/odbcinst.ini
Code bash : Sélectionner tout
sudo odbcinst -i -d -f MariaDB_odbc_driver_template.ini
L'installation doit donner un message de ce genre :
odbcinst: Driver installed. Usage count increased to 1.
Target directory is /etc

Si vous vérifiez le contenu du fichier "/etc/odbcinst.ini", vous y trouverez à la fin le contenu de notre fichier "MariaDB_odbc_driver_template.ini".

5. Création d'un Data Source Name (DSN)
Nous allons maintenant créer la définition de la source de données MariaDB qui sera interrogée par Oracle. Vous devrez bien sûr répéter cette opération pour chaque source de données à interroger.
Puisque j'ai nommé la base de données à interroger "bd_maria", nous créons un fichier "bd_maria_odbc.ini". Ce nom étant utilisé plus tard dans la configuration, si vous le changez, tenez-en compte par la suite !
Code ini : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[ODBC Data Sources] 
bd_maria=bd_maria schema data source 
  
[bd_maria] 
Driver = /usr/lib64/libmaodbc.so 
Description = ODBC for MariaDB 
SERVER = mdb.mondomaine.fr 
PORT = 3306 
USER = useroracle 
Password = User_ORA 
charset = utf8mb4 
OPTION = 3 
Database = pef 
SOCKET =
Notas :
J'ai dû remplacer le nom du serveur MariaDB par son IP et, côté MariaDB, j'ai dû changer l'utilisateur en 'useroracle'@'<ip du serveur Oracle>'.
Si votre table a un autre charset, vous pouvez le modifier. De toute manière, vous verrez par la suite que j'ai dû aussi faire une conversion explicite dans mes requêtes Oracle pour les colonnes de texte.

Installons ce fichier dans la configuration globale /etc/odbc.ini :
Code bash : Sélectionner tout
sudo odbcinst -i -s -l -f bd_maria_odbc.ini

Puis vérifions qu'on peut se connecter à la base de données MariaDB depuis le serveur Oracle avec l'utilitaire isql :
Code bash : Sélectionner tout
isql bd_maria
Vous devriez obtenir ceci :
Code bash : Sélectionner tout
1
2
3
4
5
6
7
8
9
+---------------------------------------+ 
| Connected!                            | 
|                                       | 
| sql-statement                         | 
| help [tablename]                      | 
| quit                                  | 
|                                       | 
+---------------------------------------+ 
SQL>
Et vous pouvez directement lancer des requêtes sur le serveur MariaDB :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
SQL> use bd_maria; 
SQLRowCount returns 0 
SQL> select count(*) from t_source; 
+---------------------+ 
| count(*)            | 
+---------------------+ 
| 5                          | 
+---------------------+ 
SQLRowCount returns 1 
1 rows fetched
Pour revenir à la console Linux, quittez :
Code : Sélectionner tout
SQL>quit
6. Configuration du processus d'écoute Oracle
La configuration ODBC étant terminée, passons à la configuration d'Oracle Database (rappel : la version d'Oracle utilisée est la 12.2.0.1).

Dans le fichier listener.ora, ajoutons un SID pour notre source de données ODBC :
Code bash : Sélectionner tout
1
2
cd $ORACLE_HOME/network/admin 
vi listener.ora
Voici le SID à ajouter pour l'exemple de ce tutoriel. Je lui donne le nom "sid_db_maria". Chaque Source de données ODBC doit avoir le sien et c'est le seul paramètre de cette configuration qui change :
<votre ou vos autre(s) SID>

(SID_DESC =
(SID_NAME = sid_db_maria)
(ORACLE_HOME = /produits/oracle/products/12.2.0.1/db_1)
(PROGRAM = dg4odbc)
(ENV = LD_LIBRARY_PATH=/usr/lib64:/produits/oracle/products/12.2.0.1/db_1/lib)
)

7. Création de la passerelle pour ODBC
Afin que Oracle puisse utiliser le DSN défini au chapitre 5, il faut maintenant créer une passerelle pour le service hétérogène ODBC (heterogeneous service : hs) dédié à notre source de données. Il faut donc créer un fichier de paramètres par source de données dans le répertoire $ORACLE_HOME/hs/admin et dont le nom est de la forme : init<SID>.ora. Dans notre cas, ce sera donc le fichier "initsid_db_maria.ora" :
Code ini : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# HS init parameters 
# 
HS_FDS_CONNECT_INFO = sid_db_maria 
HS_FDS_TRACE_LEVEL = DEBUG 
HS_TRACE_FILE_NAME = /var/log/odbctrace.log 
HS_FDS_SHAREABLE_NAME = /usr/lib64/libmaodbc.so 
HS_NLS_NCHAR=UTF8 
  
# 
# ODBC specific environment variables 
# 
set ODBCINI=/home/oracle/pefodbc.ini 
set LD_LIBRARY_PATH=/usr/lib64 
  
# 
# Environment variables required for the non-Oracle system 
# 
#set <envvar>=<value> 
set HOME=/home/oracle

8. Configuration du nom de service réseau Oracle
Ajoutons maintenant une entrée dans le fichier $ORACLE_HOME/network/admin/tnsnames.ora :
Code bash : Sélectionner tout
vi tnsnames.ora
Voici l'entrée à ajouter :
sid_db_maria =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = ora.mondomaine.fr)
(PORT = 1521)
)
)
(CONNECT_DATA =
(SID = sid_db_maria)
)
(HS = OK)
)

9. Création du lien de base de données (DATABASE LINK)
Nous en avons terminé avec les fichiers de configuration. Dernière étape avant d'interroger notre source de données MariaDB à partir d'Oracle : créer dans la base de données Oracle un lien vers notre source.
J'utilise ici le programme sqlplus mais vous pouvez le faire avec Sql Developer. Je crée un DATABASE LINK public mais vous pouvez le rendre spécifique à un schéma de votre BDD. Je vous renvoie à la documentation d'Oracle pour de plus amples possibilités sur cette création.
Entrons d'abord dans sqlplus :
Code bash : Sélectionner tout
sqlplus / as sysdba
Puis exécutons cette requête SQL :
Code SQL : Sélectionner tout
CREATE PUBLIC DATABASE LINK <nom du database link> connect to "<user MariaDB>" identified by "<mdp du user MariaDB>" using 'nom du dsn';
C'est à dire pour notre exemple (je nomme le database link "dbl_bd_maria") :
Code SQL : Sélectionner tout
CREATE PUBLIC DATABASE LINK dbl_bd_maria connect to "useroracle" identified by "User_ORA" using 'bd_maria';
Et nous pouvons maintenant interroger notre table MariaDB comme nous l'avions fait tout à l'heure avec isql :
Code SQL : Sélectionner tout
1
2
3
4
SELECT COUNT(*) FROM "t_source"@dbl_bd_maria; 
  COUNT(*) 
----------- 
        5

10. Quelques subtilités
1) Nommage des objets MariaDB dans les requêtes Oracle.
Vous aurez peut-être remarqué que, dans la dernière requête ci-dessus, j'ai mis le nom de la table entre guillemets. En effet, Oracle met systématiquement les requêtes en lettres capitales. Si les tables, colonnes et autres objets de la bdd MariaDB sont écrits en minuscules, alors il faut mettre ces noms entre guillemets dans les requêtes côté Oracle afin qu'il n'essaie pas d'interroger une table nommée T_SOURCE qui n'existe pas.

2) Transtypage
Bien que ma table soit en utf8mb4 dans MariaDB et que Oracle ait un characterset en principe compatible (AL16UTF16) si j'ai bien compris la doc Oracle à ce sujet, j'ai rencontré des soucis lors de la lecture des caractères accentués et spéciaux. Jai donc dû procéder à une conversion explicite dans mes requêtes Oracle :
Code SQL : Sélectionner tout
SELECT CONVERT("ma_colonne", 'WE8ISO8859P1', 'AL32UTF8') ma_colonne FROM "t_source"@dbl_bd_maria;

3) Taille des colonnes lues lors d'un import
J'ai mis en oeuvre cette technique du DATABASE LINK pour importer des données issues d'une vue MariaDB dans une table Oracle à l'aide d'une procédure Oracle contenant une requête MERGE. Alors que les largeurs des colonnes de texte soient identiques dans la source et la cible, Oracle calculait une longueur de données supérieure au nombre de caractères de la table source. J'ai dû transformer mes colonnes texte côté Oracle de VARCHAR2(<n> BYTE) en VARCHAR2(<n> CHAR) et j'ai dû TRIMer les colonnes interrogées :
Code SQL : Sélectionner tout
SELECT CONVERT(TRIM("ma_colonne"), 'WE8ISO8859P1', 'AL32UTF8') ma_colonne FROM "t_source"@dbl_bd_maria;

Une erreur dans cette actualité ? Signalez-le nous !