HSQLDB Trigger d'historisation

Bonjour,

J'essaie de convertir une base HSQLDB intégrée en standalone server. J'ai
réussi à récupérer les données, à établir le lien avec le fichier
intermédiaire .odb et à récupérer les formulaires existants. Tout va bien,
et ça va beaucoup plus vite, grâce en grande partie à la doc de
Jean-François Nifenecker.

MAIS : Mon but initial était de bénéficier d'un trigger d'historisation, qui
à chaque modification des données d'une table enregistre la valeur avant
modification (donc un trigger BEFORE UPDATE si je ne fais erreur).

Et ça ne fonctionne pas... Voici la syntaxe que j'utilise sur deux tables
test :

CREATE TRIGGER "BeforUpdateTable1" BEFORE UPDATE
ON "Table1" FOR EACH ROW
INSERT INTO "HistTable1" ("Ligne1", "Ligne2", "ID")
VALUES (OLD."Ligne1", OLD."Ligne2", OLD.ID)

Lorsque j'exécute cette commande depuis l'utilitaire SQL de LibreOffice
(Base), j'obtiens ce message :

1: user lacks privilege or object not found: OLD.Ligne1

J'ai installé SQuirreL et j'ai réussi à le faire démarrer sur MacOS (mais
ceci est une autre histoire). Lorsque je saisis la même instruction dans
SQuirreL, j'obtiens exactement le même message.

J'ai essayé un peu tous les formats d'instruction, avec ou sans OLD, avec ou
sans guillemets, j'ai créé une table dont les noms de colonnes sont tout en
majuscule, rien n'y fait, c'est toujours le même message.

Je dois avoir les privilèges voulus, puisque je suis en principe connecté SA
et que j'ai créé une colonne IDENTITE sans problème...

Bref, avez-vous une idée ? Est-ce raisonnable de vouloir utilise HSQLDB pour
cela ? Ai-je meilleur temps de passer carrément à PostgreSQL ? Pour 2-3000
lignes dans quatre ou cinq tables, ça m'a l'air d'être de l'overkill, mais
si vraiment...

Ma version de HSQLDB est 2.4. Au fait, pourquoi n'est-ce pas cette version
qui est intégrée dans LibreOffice ?

Merci d'avance !

Bonsoir,
Pour des raisons de portabilité, il est bien préférable d'utiliser des
gestionnaires de bases de données très répandus comme mysql ou
postgresql. L'un et l'autre se connectent avec Libreoffice au moyen d'un
connecteur nommé JDBC. Un avantage est de pouvoir facilement exporter la
base (mysqldump et pg_dump), ce qui permet de sécuriser les opérations.
Un autre avantage est que ces deux systèmes sont très amplement documentés.

Bonsoir Robert,

J'ai fait une première approche du côté de PostgreSQL, mais HSQLDB offre l'avantage de me permettre de récupérer les données sans aucun souci. Et puis, le volume est si faible…

Quant à MariaDB, j'ai essayé de comprendre ce qu'il faut faire pour l'installer sur le Mac et y accéder depuis LibreOffice mais là, j'ai calé. Si vous avez un fil rouge qui fonctionne, je suis prêt à tenter l'expérience…

Thierry

Bonsoir,

En fait la réponse se trouve ici : https://stackoverflow.com/questions/21753266/hsqldb-create-trigger-throws-exception-wrong-or-missing-data-impact-clause-in-d

Je n'avais pas vraiment compris la sémantique du BEFORE ou AFTER. En définissant le trigger comme AFTER j'obtiens exactement ce que je veux, tout va bien. Je peux donc poursuivre avec mon petit bricolage sans trop de soucis :wink:

Bonne soirée, merci de votre temps,

Thierry

D'après la doc hsqldb,

CREATE TRIGGER "BeforUpdateTable1" BEFORE UPDATE
ON "Table1" FOR EACH ROW
INSERT INTO "HistTable1" ("Ligne1", "Ligne2", "ID")
VALUES (OLD."Ligne1", OLD."Ligne2", OLD.ID)

deviendrait :

CREATE TRIGGER beforeUpdateTable1 BEFORE UPDATE OF Ligne1, Ligne2, ID
ON Table1
   referencing NEW ROW AS nouvelleligne
   FOR EACH ROW
   INSERT INTO "HisTable1" ("Ligne1","Ligne2", "ID") values (ligne1,
ligne2, ID)

ou peut-être que ta requete :

CREATE TRIGGER "BeforUpdateTable1" BEFORE UPDATE ON "Table1"

referencing NEW ROW AS nouvelleligne

FOR EACH ROW
INSERT INTO "HistTable1" ("Ligne1", "Ligne2", "ID")
VALUES (Ligne1, Ligne2, ID <http://OLD.ID>)

ceci en partant du principe que les valeurs OLD sont encore celle
"actuelle" vu qu'on est au Before Update...

la table nouvelleligne référence les nouvelles valeurs.

Yves

j'arrive en retard...

et effectivement, je viens de lire ça à l'instant aussi dans la doc sur le
after et before...

:slight_smile:

Oui, d'après la doc que j'ai trouvée, c'est surtout le type de trigger qui
posait problème. On ne peut pas utiliser un BEFORE pour insérer dans une
autre table, il faut impérativement utiliser un AFTER. Ensuite, je pensais
le "REFERENCING" implicite, il m'a fallu du temps pour piger qu'il fallait
l'expliciter. Mais ça, c'est dans la doc de HSQLDB contrairement à la
différence d'usage BEFORE/UPDATE.
Tout ça nous donne REFERENCING OLD ROW AS old.
J'ai d'ailleurs commencé par comprendre ce dernier point, le message
d'erreur a changé et m'a conduit à la solution. Enfin !
Finalement tout ça est très logique : On exécute le trigger après que la
modification est validée, et on peut référencer la version originale des
données par le REFERENCING OLD ROW AS... Je n'aurais pas dû ignorer la
limite liée au BEFORE, qui a priori devrait donner le même résultat avec un
REFERENCING NEW ROW... Ben non !

Thierry