Une petite question qui m’a été posée il y a quelques temps : comment stocker une image (ou tout autre document) dans une colonne de type varbinary sous SQL Server ?
Dans une base de données, le type de données varbinary(n) permet de stocker tout un ensemble de données dites de type « binaires ». Il peut s’agir d’images, de documents divers (Word, Excel, …), ou de tout autre type de données.
Dans certaines applications, on rencontre des tables de paramétrage contenant par exemple des images de référence, comme par exemple des icônes utilisés par l’applicatif. Et ces tables de référence on besoin d’être initialisées lors de la mise en production de l’applicatif. La question est donc : comment initialiser ces tables de référence ?
D’un point de vue opérationnel, toute intervention sur une base doit être scriptée, afin de pouvoir être répétée à l’identique dans tous les environnements (test, pré-production, production). Nous allons donc chercher à générer un script T-SQL en mesure d’insérer notre fichier binaire dans une table.
Une première solution consiste à utiliser un applicatif développé sur mesure pour insérer les données en base de développement, puis ensuite utiliser par exemple SSMS pour générer un script d’insertion de cette donnée, afin de pouvoir le faire passer dans tous les environnements.
Une deuxième solution consiste à utiliser la fonction OPENROWSET, qui permettra de « convertir » le fichier en expression hexadécimale.
Petite remarque au vol, l’instruction est exécutée sur le serveur, et le fichier C:\Temp\stop.ico doit donc être sur le serveur lui-même. S’il n’y a pas la possibilité de positionner directement le fichier sur le serveur, un partage réseau peut être utilisé.
Attention toutefois, l’affichage est limité à 65536 caractères, c’est-à-dire des fichiers binaires de 32Ko au maximum.
Pour les fichiers plus gros, la syntaxe ci-dessus peut être utilisée pour insérer les données dans une table, sur laquelle on pourra ensuite s’appuyer pour générer un script.
create table TableTemporaire (Data varbinary(max)) insert into TableTemporaire (Data) SELECT * FROM OPENROWSET(BULK N'C:\Temp\stop.ico', SINGLE_BLOB) AS MonImage
Dès lors, on a une table qui contient notre donnée, et l’on peut ensuite générer un script via les outils de SSMS.
Et voilà le résultat :
Un petit mélange entre les deux méthodes évoquées plus haut, et on peut désormais prendre en charge des gros fichiers binaires (et les transformer en script deux fois plus gros !).
Une recherche menée par Microsoft nomée « To BLOB or Not to BLOB: Large Object Storage in a Database or a Filesystem? » (Gray, Van Ingen, and Sears) montre que le stockage de fichiers binaire dans des varcharbinary(max) n’est pas optimisé si le fichier dépasser la taille de 256k.
http://research.microsoft.com/apps/pubs/default.aspx?id=64525
Il pourrait etre intéréssant d’évoquer l’utilisation des Filestream et comment configurer de manière optimale sons SGBD avec son sysème de stockage NTFS dans une futur billet.