lundi 30 juillet 2012

Le PL/SQL cay shitty

Je fais du PL/SQL en ce moment. Je trouve que c'est un langage un peu trop simpliste pour développer des applications. Voici une liste de repproches que je peux lui faire aujourd'hui.

Il est insentible à la casse

OK, il fonctionne à partir de la syntaxe SQL qui l'est également,. C'est un défaut pour un langage procédural pour moi car le confort de lecture du code dépend grandement de la mise en place de règles de développements (que met-on en majuscule, que met-on en minuscule, etc.) et de leur application.

Il lance des exception sans arrèt

Le langage peut gérer les exceptions. C'est bien. Toutefois des exceptions sont lancées très régulièrement. Les plus fréquentes ? NO_DATA_FOUND et TOO_MANY_ROWS. TOO_MANY_ROWS est lancée lorsqu'une requête renvoie plus d'un enregistrement. Celle-ci est logique car en PL/SQL, les requêtes sont censées valoriser es variables. Il est possible de s'assurer de renvoyer un seul résultat à coup sûr à l'aide des fonctions min / max ou en filtrant sur le rownum = 1. Ce n'est pas très sexy.

L'autre grande exception est NO_DATA_FOUND. Elle est renvoyée lorsqu'une requête ne renvoie pas de résultat. Le lancement de l'exception est inévitable : mettre mettre un NVL pour espérer renvoyer une valeur par défaut ne fonctionne pas. On n'y coupe pas : il faut gérer l'exception dans un bloc idoine.

Définition des variables

PL/SQL oblige à déclarer les variables dans un bloc DECLARE dédié. Seule exception : les variables de boucle. Il est difficile de faire des fonctions courtes en PL/SQL, à cause des requêtes qui peuvent facilement atteindre des tailles importantes. Les variables sont donc souvent utilisées loin de leur déclaration. Heureusement, il est possible de créer des blobs DECLARE / BEGIN / END imbriquées ; le prix à payer est un allourdissement du code.

Il n'y a pas de type composé

Même si PL/SQL permet de définir des types (il semble même qu'il soit possible de faire de la programmation orientée objet), il arrive souvent d'avoir besoin d'un accès rapide à un type composé, comme une liste ou un tableau associatif (liste ou tableau associatif). On peut arguer que je fais beaucoup de Python... Mais ça existe aussi en Perl, les enfants !

Assignation avec :=

... et la comparaison se fait avec un simple égal =. Qui n'a jamais fait l'erreur ?

C'est long à écrire

Je trouve que le code est particulièrement long a écrire. Beaucoup de choses se font par mot clé (for XXX LOOP YYY END LOOP, etc.). Les fonctions sont parfois tirées par les cheveux (faire un substring en se basant sur les index des caractères constitutifs de notre chaine, par exemple, est assez pénible).

Rapellons qu'il faut régalement inscrire les prototypes des fonctions dans un fichier d'en-tête si on veut qu'elles soient accessibles de d'exterieur.

Je ne sais pas si un IDE correct existe pour le PL/SQL. Extraire des fonctions est un calvaire. Je code des tests avec JUnit sous IntelliJ. J'écris le PL/SQL sous gvim. Je vous laisse imaginer lequel est le plus rapide (pourtant, j'adore gvim !).

C'est long à tester

C'est le gros problème. Le PL/SQL est très couplé à la base de données ; le code d'est d'ailleurs stockées dans des tables du dictionnaire. Exécuter et donc tester du PL/SQL demande de faire beaucoup d'accès à la base et prend beaucoup de temps. Difficile de passer sous la seconde quand on développe un jeu de tests unitaires. Sur les derniers cas de tests que j'ai codés, je tourne autour de 3 à 10 secondes pour tester 100 lignes de code. Si 100 000 tests prennent 10 000 secondes, nous perdons la possibilité de les relancer à chaque commit.

C'est monothread

Quand on travaille avec une base de données, netamment sur une application data warehouse, il y a souvent des occasions de mettre en place du parallèlisme.

Par exemple, vous pouvez aller récupérrer et mettre en forme des données venant de tables différentes, ou formant des ensembles disjoints. Le PLSQL ne donne pas la possibilité de faire des threads. C'est à la charge deu code appelant, ce qui pousse à éclater le code PLSQL si on veut réaliser des traitements en parallèle.

Bon, après écriture initiale de ce paragraphe, j'ai fait un petit tour sur stack overflow, et il se trouve qu'on peut faire des choses plus ou moins élégantes avec le DBMS_SCHEDULER. Pas évident, je trouve.

Conclusion

Le langage PLSQL a de grandes utilités. Il permet notament de réaliser des traitements batch directement dans la base de données en utilisant le moteur Oracle. C'est un langage qui présente certains aspects intéressants, notamment de donner la possibilité de configurer ses propres types de données.

Toutefois, les reporches que je lui fais dans l'article me conforte dans l'idée que la base de données doit avant tout être considérée comme un système de persistance et que le développement de la logique métier doit être déléguée dans la mesure de possible à des plateformes plus appropriées. Celles-ci permettent justement d'abstraire la logique de persistance, d'améliorer la modularité et la lisibilité de votre système.

Ami lecteur, tu peux avoir envie de me contredire. Je te laisse t'exprimer dans les commentaires.