Lorenzo Benaglia


Storie di un SQLlaro mannaro...
Archivio Posts
Anno 2010

Anno 2009

Anno 2008

Anno 2007

Anno 2006

Anno 2005
Calendario
aprile 2024
lmmgvsd
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

Come esportare su file una foto con SQL Server 2005

Già in passato mi era capitato di affrontare il discorso di esportazione di stringhe o fragments XML su file, ma la mia pelandronaggine non mi aveva ancora permesso di affrontare il discorso relativo ai Binary Large Objects (BLOBs).

Prendendo spunto da un post apparso ieri su microsoft.public.it.sql, ho provato ad analizzare la questione giungendo ad una soluzione che vorrei proporre.
Teo domandava:

Ho delle immagini in una tabella su sql server 2005 express.
E' possibile vederle da SqlServer?

SQL Server 2005 non offre alcun tool per la visualizzazione di immagini contenute in un database, pertanto occorre "ingegnarsi" scrivendo una piccola applicazione client oppure sfruttando l'integrazione con il CLR per realizzare ad esempio una stored procedure che permetta il salvataggio su disco delle immagini.

Ovviamente ho scelto la seconda strada

Prima di tutto ho creato la tabella dbo.Students nel mio database di lavoro, popolandola con 1 riga di esempio:

USE Work;

GO

 

/* Definisto la tabella dbo.Students */

CREATE TABLE dbo.Students(

StudentID int NOT NULL IDENTITY PRIMARY KEY,

FirstName varchar(10) NOT NULL,

LastName varchar(10) NOT NULL,

Photo varbinary(max) NOT NULL

);

GO

 

DECLARE @Photo varbinary(max);

 

/* Carico un file jpeg in una variabile varbinary(max) */

SET @Photo = (

      SELECT Q.BulkColumn

      FROM OPENROWSET(BULK 'D:\documenti\Immagini\Canon5D.jpg', SINGLE_BLOB) AS Q

);

 

/* Popolo la tabella dbo.Students */

INSERT dbo.Students VALUES('Lorenzo', 'Benaglia', @Photo);

GO

 

SELECT *

FROM dbo.Students;

GO

 

/* Output:

 

StudentID   FirstName  LastName   Photo

----------- ---------- ---------- ------

1           Lorenzo    Benaglia   0xFFD8...

 

(1 row(s) affected)

 

*/

A questo punto ho lanciato SQL Server Business Intelligence Development Studio, definendo un nuovo progetto database in C# chiamato "SQLCLRUtility" ed aggiungendo una Stored Procedure chiamata "SaveBLOBTofile" con il seguente codice:

using System;

using System.Data;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using Microsoft.SqlServer.Server;

using System.IO;

 

public partial class StoredProcedures

{

    [Microsoft.SqlServer.Server.SqlProcedure]

    public static void SaveBLOBToFile(Byte[] Data, String DestFile)

    {

        FileStream fs = new FileStream(DestFile, FileMode.Create, FileAccess.Write);

        fs.Write(Data, 0, Data.Length);

        fs.Close();

 

        SqlContext.Pipe.Send(String.Format("BLOB data successfully saved to file '{0}'", DestFile));

    }

};

Come potete vedere il codice è estremamente semplice: la stored procedure riceve in input un array di Bytes ed il nome del file che vogliamo creare.
Il corpo della procedura si limita ad istanziare la classe FileStream e a richiamare il metodo Write per scrivere l'array di bytes nel file passato come argomento.
Tutto qua

Compilando il progetto otterremo l'assembly SQLCLRUtility.dll che andremo a "deployare" manualmente nel database Works.
Apriamo il SQL Server Management Studio, selezioniamo il bottone New Query ed incollamo il seguente script (modificando oppurtunamente il path dell'assembly SQLCLRUtility.dll):

USE Work;

GO

 

/* Imposto a ON la proprietà TRUSTWORTHY

** in modo da poter accedere alle risorse esterne al database

*/

ALTER DATABASE Work SET TRUSTWORTHY ON;

GO

 

/* Creo l'assembly */

CREATE ASSEMBLY SQLCLRUtility

AUTHORIZATION dbo

FROM 'C:\...\SQLCLRUtility.dll'

WITH PERMISSION_SET = EXTERNAL_ACCESS;

GO

 

/* Creo la stored procedure dbo.up_SaveBLOBToFile */

CREATE PROCEDURE dbo.up_SaveBLOBToFile

      @Data varbinary(max),

      @DestFile nvarchar(256)

WITH EXECUTE AS CALLER

AS

EXTERNAL NAME [SQLCLRUtility].[StoredProcedures].[SaveBLOBToFile];

GO

Ora possiamo richiamare la stored procedure nel seguente modo:

DECLARE @Photo varbinary(max);

 

SELECT @Photo = Photo

FROM dbo.Students

WHERE StudentID = 1;

 

EXEC dbo.up_SaveBLOBToFile @Data = @Photo, @DestFile = 'C:\Canon5D.jpg';

 

/* Output:

 

BLOB data successfully saved to file 'C:\Canon5D.jpg'

 

*/

 

/* Pulizia */

DROP TABLE dbo.Students;

DROP PROCEDURE dbo.up_SaveBLOBToFile;

DROP ASSEMBLY SQLCLRUtility;

!!DEL C:\Canon5D.jpg

Con quest'ultima procedura di esportazione penso di aver coperto un po' tutte le casistiche.

Categoria: SQL Server
giovedì, 14 giu 2007 Ore. 10.43
Statistiche
  • Views Home Page: 933.307
  • Views Posts: 698.334
  • Views Gallerie: 12.661.499
  • n° Posts: 300
  • n° Commenti: 314
Mappa





















Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003