A la recherche d'un client SQL en ligne de commande java

Contexte

Il est parfois nécessaire d'accéder aux données d'une base SQL externe, sans avoir forcément sur le poste les clients SQL propres à la plate-forme (sql*plus, mysql-client, etc).
Dans ce contexte, l'utilisation d'un client Java, utilisant JDBC, permet d'accéder à de multiples bases, pour peu que l'on dispose des bons drivers.
Une recherche sur internet mène rapidement vers java-source.net/open-source/sql-clients, qui liste des clients Java.

Recherchant uniquement des clients utilisables en ligne de commande (sur un serveur sans affichage X11), j'ai finalement retenu ces différentes solutions à tester :

  • DataBase Java Console (DBJC)
  • jisql
  • sqlshell
  • jsqsh

 

J'ai donc testé ces différentes solutions, pour tenter d'en trouver une qui soit la mieux adaptée à mes besoins, à savoir :

  • Utilisation en ligne de commande
  • Déploiement simple
  • Scriptable : utilisable dans un script shell avec un fichier de paramètres, sans intervention manuelle
  • Permettant les SELECT mais aussi les mises à jour et plus généralement toutes opérations SQL
  • sous licence libre, évidemment

Toutes ces solution sont sous licence libre.

DataBase Java Console (DBJC)

Présentation

DataBase Java Console (DBJC) est un projet accessible sur nioto.com/dbjc/. Il semble assez ancien, car le contenu de l'archive date de Mai 2002.

Installation

L'installation est très simple : il suffit de décompresser l'archive, qui comprend :

  • Un répertoire lib, qui contient le fichier jar
  • Un fichier README, expliquant le mode d'utilisation
  • Un fichier d'exemple de propriétés
  • Un répertoire src, comprenant les sources

Utilisation

dbjc s'utilise toujours conjointement avec un fichier .properties, qui définit le type de driver, l'utilisateur et son mot de passe, mais également les requêtes SQL à utiliser. Exemple type d'utilisation

CLASSPATH=/data/progs/squirrel-sql-3.4.0/lib/ojdbc-11.1.0.7.jar:/data/opt/jdbc/dbjc/lib/dbjc.jar 
export CLASSPATH

java -cp $CLASSPATH com.nioto.dbjc.Main test.properties 
Choose a query:
0: Quit program
1: select * from PRA_PRF_APP where nsq_obj > 610000
2: Select Profils d'une Application
enter your choice: 2
Enter param value for param # 1 ( string ):620613
Results:
-------
NSQ_PRA = 195
NSQ_OBJ = 620613
COD_UTL_PRA = ADMIN
<enter> for next, or q to quit:
--
NSQ_PRA = 196
NSQ_OBJ = 620613
COD_UTL_PRA = DEFAULT
<enter> for next, or q to quit:
--
NSQ_PRA = 275
NSQ_OBJ = 620613
COD_UTL_PRA = TEST

<enter> for next, or q to quit:
--
enter your choice: 0
exiting ...

Comme on peut le voir, les fonctionnalités sont assez restreintes. L'affichage des résultats, notamment, n'est pas très exploitable, car il faut taper sur la touche Entrée pour faire défiler tous les résultats. Il n'est pas possible d'exporter le résultat sous forme d'un fichier, et seules les requêtes SELECT sont utilisables.

Conformité aux exigences

  • Utilisation : restreinte. Nécessite un fichier de propriétés, qui définit les opérations SELECT possibles
  • Déploiement : très simple
  • Scriptable : non. Demande toujours une intervention sur le clavier
  • Opérations SQL: SELECT uniquement, prédéfinies
  • Licence : GPL v2

Cette solution est simple à installer, mais peu utilisable au final pour mes besoins.

jisql

Présentation

jisql est un projet accessible sur www.xigole.com/software/jisql/jisql.jsp. Les fichiers de l'archive datent de Septembre 2011.

Installation

Le fichier zip est simplement décompressé. Il contient :

  • build.xml : fichier de build java
  • javadoc : répertoire contenant la documentation au format Javadoc
  • lib : répertoire contenant les jars
  • runit : exemple d'utilisation pour unix/linux
  • runit.bat : exemple d'utilisation pour Windows
  • runit_query : exemple d'utilisation avec requête
  • src : répertoire contenant les sources

Utilisation

jisql se lance via une ligne de commande :

CLASSPATH=/data/progs/squirrel-sql-3.4.0/lib/ojdbc-11.1.0.7.jar:/data/opt/jdbc/jisql-2.0.11/lib/jisql-2.0.11.jar:/data/opt/jdbc/jisql-2.0.11/lib/jopt-simple-3.2.jar
export CLASSPATH

DBUSER=scott
DBPASS=tiger
DRIVER=oracle.jdbc.driver.OracleDriver
DBURL=jdbc:oracle:thin:@lnxql99723005.example.com:1521:MUTU
export CLASSPATH
java -cp $CLASSPATH com.xigole.util.sql.Jisql -user $DBUSER -password $DBPASS -driver $DRIVER -cstring $DBURL -c \;

Enter a query:
1 > select  * from PRA_PRF_APP where nsq_obj > 610000;
               NSQ_PRA |                NSQ_OBJ |                                                                      COD_UTL_PRA | 
-----------------------+------------------------+----------------------------------------------------------------------------------|
                   195 |                 620613 |                                                                            ADMIN | 
                   196 |                 620613 |                                                                          DEFAULT | 
                   275 |                 620613 |                                                                             TEST | 

Enter a query:
1 > exit

jisql dispose de plusieurs options intéressantes, tel que :

  • -input : nom d'un fichier comprenant les commandes à exécuter
  • -query : requête SQL à exécuter
  • -formatter : type de formatage en sortie (csv, xml, default)

Par exemple, avec le script jdbctest qui contient le code :

#!/bin/sh
CLASSPATH=/data/progs/squirrel-sql-3.4.0/lib/ojdbc-11.1.0.7.jar:/data/opt/jdbc/jisql-2.0.11/lib/jisql-2.0.11.jar:/data/opt/jdbc/jisql-2.0.11/lib/jopt-simple-3.2.jar
export CLASSPATH

DBUSER=scott
DBPASS=tiger
DRIVER=oracle.jdbc.driver.OracleDriver
DBURL=jdbc:oracle:thin:@lnxql99723005.example.com:1521:MUTU
export CLASSPATH
java -cp $CLASSPATH com.xigole.util.sql.Jisql -user $DBUSER -password $DBPASS -driver $DRIVER -cstring $DBURL -c \;

DBQUERY="select * from PRA_PRF_APP where NSQ_OBJ > 610000;"

echo "Formatter CSV"
java -cp $CLASSPATH com.xigole.util.sql.Jisql -user $DBUSER -password $DBPASS -driver $DRIVER -cstring $DBURL -c\; -formatter csv -query "$DBQUERY"

echo " "
echo "Formatter XML"
java -cp $CLASSPATH com.xigole.util.sql.Jisql -user $DBUSER -password $DBPASS -driver $DRIVER -cstring $DBURL -c\; -formatter xml -query "$DBQUERY"

L'exécution de ce script donne les résultats suivants :

  
./jdbctest
Formatter CSV
195,620613,ADMIN
196,620613,DEFAULT
275,620613,TEST

Formatter XML
<<?xml version="1.0" encoding="utf-8" ?>
<<NSQ_PRA>195<<NSQ_OBJ>620613<<COD_UTL_PRA>ADMIN
<<NSQ_PRA>196<<NSQ_OBJ>620613<<COD_UTL_PRA>DEFAULT
<<NSQ_PRA>275<<NSQ_OBJ>620613<<COD_UTL_PRA>TEST

Il est également possible de donner des options supplémentaires pour le formattage CSV : délimiteur, nom des colonnes.

Conformité aux exigences

  • Utilisation : possible en ligne de commande sans interaction
  • Déploiement : simple
  • Scriptable : oui, possibilité d'utiliser un fichier pour les commandes à exécuter, et export en CSV ou XML
  • Opérations SQL: toutes,
  • Licence : Apache 2.0

jisql correspond bien à nos besoins. Il permet un fonctionnement en ligne de commande ou en script, permet de formatter les résultats sous diverses formes, exploitables par des programmes, et peut être complètement piloté par un fichier de requête.
De plus, il est livré avec ses sources et la javadoc, et on peut très facilement l'intégrer dans un script, vu le peu de dépendance et la taille réduite (88 ko pour les 3 librairies).

jsqsh

Présentation

jsqsh, disponible sur sourceforge.net/projects/jsqsh, et un client shell SQL, recommandé par IBM (cf.).

Il se positionne comme un concurrent / remplaçant de SQL*Plus, avec des fonctionnalités assez semblables : historiques des commandes, utilisation de variables, formatage de sortie adaptable (CSV, etc).

La dernière version 2.0 date du mois d'Août 2012.

jsqsh peut s'installer à partir des sources, ou à partir d'un fichier RPM ou DEB.
J'ai eu des difficultés pour le faire fonctionner avec une base Oracle (Erreur ORA-12504). La solution fonctionne bien avec du MySQL.

Installation

Sur une plate-forme Linux, l'installation est très simple. Elle peut se faire à partir du fichier RPM ou DEB.
Dans tous les cas, il existe aussi une archive sous forme de fichier ZIP, qu'il suffit de décompresser. L'archive comprend :

  • bin : répertoire avec les scripts permettant de lancer jsqsh
  • share : répertoire contenant les librairies java utilisées

L'ensemble des librairies "pèse" 2,2 Mo.

Utilisation

Conformité aux exigences

  • Utilisation : ok.
  • Déploiement : ok. Simple via les paquets ou l'archive
  • Scriptable : oui. On peut lancer un script SQL en paramètres
  • Opérations SQL: toutes les opérations sont possibles
  • Licence : Apache v2

jsqsh est une solution complète, qui peut remplacer un outil tel que SQL*Plus. Il peut être un peu surdimensionné par rapport à nos besoins assez simples.
Du fait de l'impossibilité de se connecter à une base Oracle, cette solution ne sera pas retenue.

L'analyse des logs Oracle donne les éléments suivants, avec deux solutions différentes, pour une connexion sur la même base : .
Avec jisql :

12-AUG-2013 15:56:09 * (CONNECT_DATA=(SID=ENROLE)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=vliefooghe))) * (ADDRESS=(PROTOCOL=tcp)(HOST=128.240.165.11)(PORT=48056)) 
* establish * ENROLE * 0

Avec jsqsh

Mon Aug 12 15:57:39 2013
12-AUG-2013 15:57:39 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=__jdbc__)(USER=vliefooghe))(SERVICE_NAME=)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=vliefooghe))) 
* establish * 12504
TNS-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA
 TNS-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA

Dans le deuxième cas, il manque bien le passage du paramètre SID. Je n'ai pas eu le courage ni le temps de récupérer les sources pour corriger le problème, d'autant plus que la solution me paraissant un peu trop "riche" pour mes besoins.

 

SQL Shell

Présentation

SQL Shell est un projet qui remplace un terminal complet, et inclut par exemple la complétion de commandes, l'historique, etc. La dernière version date de Janvier 2010.
Le site du projet est http://sqlshell.sourceforge.net.

Installation

Le fichier zip est simplement décompressé. Il contient :

  • db : répertoire de configuration des bases de données
  • lib : répertoire contenant les jars et librairies
  • ChangeLog : journal des modifications
  • db.properties : exemple de fichier de configuration de base de données
  • README : fichier d'aide
  • sqlshell : script principal à exécuter sous linux/unix
  • sqlshell.bat : script principal à exécuter sous Windows
  • sqlshell.jar : archive java du programme

L'ensemble représente 2,5 Mo.

Si vous avez une machine Linux 64bits, il faut récupérer les librairies sur sourceforge.net/projects/javacurses/, et les copier dans le répertoire lib aux côtés de la librairie java.

Utilisation

L'application utilise jcurses, et offre une interface complète de terminal.

Conformité aux exigences

  • Utilisation : propose un mode ligne de commande évolué, mais aussi l'utilisation de scripts
  • Déploiement : assez simple, demande de disposer des bonnes librairies (fournies avec la solution, sauf les version 64bits)
  • Scriptable : utilisation de script SQL externes possible
  • Opérations SQL: toutes les opérations sont possibles
  • Licence : Apache 2.0

sqlshell semble être une solution assez intéressante, dédiée à un usage interactif plutôt qu'à embarquer dans des scripts (même si c'est faisable). Les fonctionnalités de rappel de commande, édition d'une ligne, dump, etc. rendent l'outil assez sympathique à utiliser.

Conclusion

Suite aux différents tests réalisés, la solution jisql me semble être la plus intéressante : simple à utiliser, souple au niveau formattage, elle peut facilement être utilisée en mode script. Elle est également légère à installer.

Autres solutions

sqlshell

Homonyme d'une autre solution, il s'agit d'une application scala. Disponible sur software.clapper.org/sqlshell. L'application fait plus de 10 Mo, dispose d'un installeur graphique... et donne une impression de sérieux : bien documenté, fonctionnalités assez complètes.

Je ne l'ai cependant pas (encore ?) testé

Et vous, quelle est votre solution fétiche pour accéder à vos bases SQL en java ?

Catégorie: 

Tag: