dimanche 6 avril 2014

Variables dans psql

Il nous est loisible de définir et d'utiliser dans un terminal psql des variables sur le modèle des host variables qui existent pour du SQL embarqué dans un programme C (ou cobol).
Illustrons ce fait à l'aide d'instruction portant sur la table opérations définie ici:


(Remarquons que la méta-commande \pset numericlocale on concerne uniquement le format de sortie des nombres)
Autre exemple:


Malheureusement l'instruction
SELECT ...
INTO ...
sert au niveau de psql à créer une nouvelle table et non pas à stocker le résultat d'une requête dans une variable (contrairement à ce qui existe pour le SQL embarqué).
Il est cependant possible de contourner le problème comme dans cet exemple:


Les tables dépenses et utilisations ont été définies pour l'article Le piège du null. Depuis le libellé 'Médecin' a été remplacé par 'Santé' et un code a été attribué à toutes les dépenses.

Terminons par un exemple montrant les avantages de l'utilisation de telles variables.
Modifions comme ceci le fichier bilan.sql figurant dans ce billet:

\set QUIET
\set an 2013
\set titre 'Bilan ':an
\pset numericlocale on
\pset footer off
\pset linestyle u
\pset title :titre
\pset border 2
\o | awk 'NR==4 {y=$0};/SOUS-TOTAL/ {print y;print;print y};!/SOUS-TOTAL/'
SELECT mois_n ||'-' || mois AS "Mois",  '' AS " ", reference,
date_exec::text, crédit, débit,
  (SELECT SUM(solde)
  FROM opérationsv B
  WHERE B.reference <= A.reference
  AND B.an = A.an
  AND B.mois_n = A.mois_n) AS solde,
  contrepartie AS "usage"
FROM opérationsv A
WHERE an = :'an'
UNION
SELECT mois_n || '-' || mois, 'SOUS-TOTAL', '', '',
SUM(crédit) AS crédit, SUM(débit) AS débit, SUM(solde) AS solde,
'' AS " "
FROM opérationsv
WHERE an = :'an'
GROUP BY mois_n, mois
UNION
SELECT 'Ensemble', 'TOTAL', '', '',
SUM(crédit) AS crédit, SUM(débit) AS débit, SUM(solde) AS solde,
'' AS " "
FROM opérationsv
WHERE an = :'an'
ORDER by 1, 2 , 3;
\pset footer
\pset title
\pset border 1
\unset QUIET
\o

Comparant avec le fichier original, nous constatons que pour passer du bilan 2013 au bilan 2014, il nous suffit maintenant de remplacer 2013 par 2014 en un seul endroit (au lieu de 4).

Une autre possibilité est de supprimer \set an 2013 du fichier bilan.sql: le même fichier d'instructions pourra alors servir pour n'importe quelle année (il faut bien sûr initialiser la variable an):