truc2geek

2012/05/05

SQLite, part 5 : PRAGMA encoding, fichier d’instructions SQL

Filed under: SQLite — Étiquettes : , , , , , , , , , , — truc2geek @ 20:35

PRAGMA encoding

on reprend la BD BaseTest2.db dans son état suite au dernier article, on la copie dans D:\Test.
pour télécharger ce fichier, suivez ce lien

on ouvre la console DOS, on ouvre la BD, on active PRAGMA foreign_keys.

on ajoute un enregistrement « société » avec une valeur contenant un accent pour le champ « nom » :
INSERT INTO T_Societe
(nom, info)
VALUES (‘La Forêt’, ‘nouveau client’);

on vérifie le résutlat :
SELECT * FROM T_Societe;
1:AlimPlus:1er client
3:Le Verger:gros client
4:Fast Courses:
5:L’Epicerie du Centre
6:La Forêt:client

dans mon cas (avec la version 3.7.11 de SQLite), l’encodage utilisé par défaut restitue bien « La Forêt », tout va bien.

Pour voir quel encodate est utilisé :
PRAGMA encoding;

Si le « ê » est mal affiché : cela signifie que l’encodage utilisé par défaut n’accepte pas les caractères spéciaux.
Il faut alors définir la valeur de PRAGMA encoding à UTF-8 :
PRAGMA encoding = UTF-8;

D’après la doc sur le site, il n’est pas possible de redéfinir l’encodage d’une BD « après l’avoir créée ».
Quelques essais montrent que, pour redéfinir l’encodage d’une BD, il faut le faire avant toute création de table,
sinon la commande est sans effet.
Donc pour une version de SQLite dans laquelle l’encodage par défaut n’est pas UTF-8, voici comment faire pour créer une BD
dont l’encodage sera UTF-8 :
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest3.db (où BaseTest3.db n’existe pas encore, sinon SQLite ouvre l’existante)
PRAGMA encoding = UTF-8;
PRAGMA foreign_keys = ON;

instructions de création des tables (créer au moins 1 table)
.exit

créer un fichier texte contenant des instructions SQL

entrer une à une les instructions SQL dans la console est un peu laborieux.
mais on peut écrire toutes nos instructions SQL dans un fichier, puis toutes les exécuter en une seule commande dans la console.
C’est plus rapide, et plus pratique puisqu’on conserve ainsi une trace des instructions SQL exécutées.
On peut utiliser n’importe quel éditeur de texte.

1er essai

on commence notre fichier par l’instruction qui active la gestion de l’intégrité référentielle :
PRAGMA foreign_keys = ON;

si nécessaire (pour un fichier d’instructions qui sera utilisé pour créer une nouvelle BD), on définit UTF-8 comme encodage  :
PRAGMA encoding = « UTF-8 »;

on écrit ensuite les instructions SQL suivantes, sachant qu’on peut laisser autant de lignes vides qu’on veut entre deux instructions :

INSERT INTO T_Societe
(nom, info)
VALUES (‘StockAlfa’, ‘déstockage’);

INSERT INTO T_Societe
(nom)
VALUES (‘La Ferme Bio’);

INSERT INTO T_Societe
(nom)
VALUES (‘Marché Urbain’);

INSERT INTO T_Societe
(nom)
VALUES (‘Le Nouveau Marché’);

INSERT INTO T_Societe
(nom)
VALUES (‘Le Panier’);

INSERT INTO T_Societe
(nom)
VALUES (‘Super Deal’);

INSERT INTO T_Societe
(nom)
VALUES (‘MarketPlus’);

INSERT INTO T_Societe
(nom)
VALUES (‘La Bonne Récolte’);

INSERT INTO T_Societe
(nom)
VALUES (‘Rayon Frais’);

INSERT INTO T_Societe
(nom)
VALUES (‘Caddie Dollar’);

on fait une copie de sauvegarde de la BD

on exécute toutes les instructions du fichier :
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db <D:\Test\isql.txt

ouvrir la BD pour vérifier :
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db

certains caractères accentués sont mal affichés :
en fait tous, sauf celui de l’enregistrement ‘La Forêt’, qu’on a créé « manuellement » dans la console.

on ferme la BD :
.exit

on copie le fichier d’instructions SQL et le fichier BaseTest2.db dans un dossier, pour y revenir ensuite.
on garde le fichier d’instructions SQL et on supprime BaseTest2.db, on reprend la version de BaseTest2.db qu’on avait sauvegardée avant de lancer l’exécution du fichier texte sur la BD.

2e essai

peut-être que l’encodage du fichier texte est en cause?
dans Notepad++, menu « Encodage » :
l’option « Encoder en ANSI » est sélectionnée.
Je sélectionne « Encoder en UTF-8 »

Les caractères accentués sont tous changés en « E9 » pour « é » par exemple

on réécrit ces caractères un par un, on sauvegarde  et on essaie

on exécute toutes les instructions du fichier, puis on ouvre la BD pour vérifier  :
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db <D:\Test\isql.txt
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db

la console retourne une erreur

SQLite3 semble avoir lu deux caractères avant « PRAGMA », sur la première ligne de mon fichier.
Pour avoir déjà eu ce genre de problèmes en PHP pour utiliser les sessions (le fichier .php doit impérativement commencer par l’instruction « session_start(); » sans rien devant), je suppose que c’est le BOM, Byte Order Mark (voir Wikipédia), qui cause cette erreur.

Pour vérifier cette hypothèse, j’ouvre mon fichier avec un éditeur de texte hexadécimal, par exemple Hex Editor Neo
Voici le logiciel au lancement, on clique sur l’icône « Open File »

on sélectionne le fichier texte, on valide

On constate qu’en effet, quelque chose est placé avant le mot « PRAGMA ».

on copie le fichier d’instructions SQL et le fichier BaseTest2.db dans un dossier, pour y revenir ensuite.
précision : même si à cause du BOM, la première instruction du fichier texte (PRAGMA foreign_keys = ON;) n’a pas été exécutée, toutes les autres l’ont été.
on garde le fichier d’instructions SQL et on supprime BaseTest2.db, on reprend la version de BaseTest2.db qu’on avait sauvegardée.

3e essai

dans Notepad++, menu « Encodage », on sélectionne « Encoder en UTF-8 (sans BOM) », on sauvegarde

on sauvegarde et on essaie

C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db <D:\Test\isql.txt
cette fois, la console ne retourne aucune erreur

on ouvre la BD et affiche le contenu de la table :
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db
SELECT * FROM T_Societe;

Les caractères accentués présents dans le fichier d’instructions SQL sont affichés différemment, mais toujours mal.

on ferme la BD :
.exit

vérifier avec SQLite Expert

on a essayé plusieurs solutions pour utiliser des caractères spéciaux dans un fichier d’instructions SQL, et apparemment sans succès.
mais c’est peut-être simplement la console qui les affiche mal?
on va vérifier ça en allant voir, avec SQLite Expert, directement le contenu des différents jeux de la BD.

la BD du 1er essai :

la BD du 2e essai

la BD du 3e essai

Les fichiers encodés en UTF-8 sont ok, et il faut plus précisément utiliser UTF-8 sans BOM, puisque sinon la 1e ligne du fichier ne pourra être interprétée correctement.

On remarque par contre que dans les trois cas, le caractère accentué présent dans la chaîne SQL écrite et exécutée directement dans la console, pour la société « La Forêt », est ignoré.

chcp 65001

on recherche donc quelle peut être la cause au niveau de la console, voici un exemple de lien intéressant avec les mots-clés « console dos encodage »

on entre « mode CON » :

on peut aussi entrer uniquement « chcp » pour connaître seulement l’encodage utilisé par la console :
chcp
résultat :
Page de codes active : 850

pour modifier l’encodage :
chcp 1252
résultat :
Page de codes active : 1252

Wikipédia donne beaucoup d’informations sur le sujet

on paramètre l’encodage 65001, correspondant à UTF-8
chcp 65001
on s’attend à une réaction comme « Page de codes active : 1252 » mais non…?

nouvelle recherche Google, avec « sqlite3 console chcp », on a la solution en suivant ce lien

on modifie la police de la console
faire un clic droit sur la partie haut de la fenêtre de la console

et cliquer sur « Propriétés »

sélectionner la police « Lucida Console »

valider

entrer chcp 65001
cette fois la console réagit :
Page de codes active : 65001

on réouvre la BD :
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db
SELECT * FROM T_Societe;

4e essai

on reprend la BD telle qu’elle était à la fin de l’article précédent
(vous pouvez la télécharger ici [LIEN])

on est donc bien en 65001 dans la console.

on ouvre la BD et crée un enregistrement sans accent.
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db

INSERT INTO T_Societe
(nom)
VALUES (‘jack’);
ok

on essaie avec un accent
INSERT INTO T_Societe
(nom)
VALUES (‘ébène’);
–> erreur, on est sorti de sqlite3

on réouvre la BD pour lister le contenu de T_Societe :
l’enregistrement « ébène » n’a en effet pas été pris en compte…

on referme la BD pour exécuter le fichier d’instructions SQL:
.exit

C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db <D:\Test\isql.txt
pas de message d’erreur, c’est plutôt bon signe

C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db

tout est bien affiché.

on ferme la BD pour voir ce que ça donne dans SQLite Expert
.exit

on clique sur l’icône « + » pour ajouter un enregistrement comprenant des accents, on valide

on ferme la BD dans SQLite Expert pour l’ouvrir dans la console :
C:\SQLite\v-3-7-11\sqlite3 D:\Test\BaseTest2.db
SELECT * FROM T_Societe;

L’enregistrement avec les caractères spéciaux qu’on a créé via SQLite Expert est affiché correctement.

donc avec la BD paramétrée avec l’encodage UTF-8 et la console paramétrée avec la page de codes 65001, les caractères spéciaux
sont bien affichés.
le seul problème est qu’on ne peut plus créer via la console, un enregistrement comportant des caractères spéciaux.
mais en fait ce n’est pas vraiment un problème puisque la finalité d’une BD est d’être utilisée dans une application, par un langage tel que Python, par exemple.

Publicités

Laisser un commentaire »

Aucun commentaire pour l’instant.

RSS feed for comments on this post. TrackBack URI

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Créez un site Web ou un blog gratuitement sur WordPress.com.

%d blogueurs aiment cette page :