Comment lire et écrire un fichier vers et depuis une colonne BLOB à l'aide de segmentation dans ADO.NET et Visual C# .NET

Traductions disponibles Traductions disponibles
Numéro d'article: 317043 - Voir les produits auxquels s'applique cet article
Pour une version de Microsoft Visual Basic .NET de cet article, voir 317034.
Pour une version de Visual C++ .NET de cet article, voir 317044.
Agrandir tout | Réduire tout

Sommaire

Résumé

Cette étape par étape explique comment utiliser les instructions de Microsoft SQL Server READTEXT et UPDATETEXT afin de lire et écrire des données des colonnes BLOB (LongVarBinary) dans une table de base de données.

En raison de contraintes de réseau, vous devrez peut-être récupérer un grand fichier BLOB de segments plus petits puis élément les morceaux ensemble au lieu de récupérer le BLOB ensemble de fichiers en même temps. Cependant, les fournisseurs de données ADO.NET inutile méthodes GetChunk et AppendChunk disponibles pour les DAO (Data Access Object) et les objets ActiveX Data Objects (ADO) jeu d'enregistrements . Cet article décrit différentes façons de récupérer des données en segments plus petits.

notes :
  • Cet article contient des exemples pour les deux les données SqlClient fournisseur et le fournisseur OLE DB .NET données. Les différences uniquement, à part les noms de classe sont les chaînes de connexion et la déclaration de paramètres SQL. La technique fondamentale pour récupérer les instructions READTEXT et UPDATETEXT est identique.
  • L'enregistrement test de la table Catégories de l'exemple de base de données n'existe pas de Northwind. Vous devez utiliser l'Explorateur de serveurs ou un autre outil pour ajouter un enregistrement avec le nom de catégorie définie sur test . Après avoir utilisé les exemples suivants, vous souhaiterez peut-être supprimer cet enregistrement de la base de données. Pour supprimer l'enregistrement, tapez la commande suivante dans l'Analyseur de requêtes SQL et puis appuyez sur F5 :
    use Northwind
    delete from Categories where CategoryName = 'Test'
    					

Requirements

Les éléments suivants décrivent le matériel recommandé, les logiciels, infrastructure réseau, compétences et connaissances, service packs sont requis :
  • Microsoft Windows 2000 Professionnel, Windows 2000 Server, des Windows 2000 Advanced Server ou Microsoft Windows NT 4.0 Server
  • Microsoft Visual Studio .NET
  • Microsoft SQL Server 7.0 ou version ultérieure
Cet article suppose que vous êtes familiarisé avec ADO.NET principes de base et syntaxe.

Create a project and add code

  1. Ouvrez l'Analyseur de requêtes SQL.
  2. Tapez la commande suivante et appuyez sur F5 pour passer de la base de données par défaut à Northwind :
    use Northwind
  3. Tapez la commande suivante et appuyez sur F5 pour insérer un nouvel enregistrement dans la table Catégories de la base de données Les Comptoirs :
    Insert into categories(categoryname) values ('Test')
    Remarque il est uniquement nécessaire pour ajouter cet enregistrement à la table Catégories si vous souhaitez utiliser cet exemple montre comment sans modification des données existantes dans cette table.
  4. Dans Visual Studio .NET, créer un nouveau Visual C# .NET Windows projet d'application.
  5. Athe haut de votre fichier Form1.cs, ajoutez les lignes deux suivantes de code pour ajouter des références à votre projet pour System.Data.SQLClient et System.Data.OLEDB :
    using System.Data.SqlClient;
    using System.Data.OleDb;
  6. Ajoutez quatre boutons à Form1. Modifiez la propriété des boutons en SQLBlob2File OlDbBlob2File , File2OleDbBlob et File2SqlBlob , respectivement.
  7. Ajoutez les déclarations variable chaîne suivantes sous la classe publique Form1 :
    string destfilepath;
    string sourcefilepath;
    					
  8. Collez le code suivant dans l'événement Load du formulaire :
    destfilepath = @"c:\mytest.bmp";
    sourcefilepath = @"c:\windows\coffee bean.bmp";
    					
  9. Appelez les procédures de l'événement Click pour chaque bouton :
    // Click event for the button labeled SqlBlob2File.
    SqlChunkBlob2File(destfilepath);
    
    // Click event for the button labeled OLDbBlob2File.
    OlDbChunkBlob2File(destfilepath);
    
    // Click event for the button labeled File2OleDbBlob.
    ChunkFile2OleDbBlob(sourcefilepath);
    
    //Click event for the button labeled File2SqlBlob.
    ChunkFile2SqlBlob(sourcefilepath);
    					
    ChunkFile2SqlBlob(sourcefilepath) ;
  10. Coller quatre fonctions dans Form1 :
    public void SqlChunkBlob2File(string DestFilePath)
    {
       try
       {
    	int PictureCol  = 0;  // position of Picture column in DataReader
    	int BUFFER_LENGTH  = 32768; // chunk size
    	SqlConnection cn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");
    			
    	// Make sure Photo is non-NULL and return TEXTPTR to it.
    			
    	SqlCommand cmdGetPointer = new SqlCommand("SELECT @Pointer=TEXTPTR(Picture), @Length=DataLength(Picture) FROM Categories WHERE CategoryName='Test'", cn);
    	SqlParameter PointerOutParam = cmdGetPointer.Parameters.Add("@Pointer", SqlDbType.VarBinary, 100);
    	PointerOutParam.Direction = ParameterDirection.Output;
    	SqlParameter LengthOutParam  = cmdGetPointer.Parameters.Add("@Length", SqlDbType.Int);
    	LengthOutParam.Direction = ParameterDirection.Output;
    	cn.Open();
    	cmdGetPointer.ExecuteNonQuery();
    	if(PointerOutParam.Value == null) 
    	{
    		cn.Close();
    		// Add code to handle NULL BLOB.
    		return;
    	}
    			
    	// Set up READTEXT command, parameters, and open BinaryReader.
    			
    	SqlCommand cmdReadBinary = new SqlCommand("READTEXT Categories.Picture @Pointer @Offset @Size HOLDLOCK", cn);
    	SqlParameter PointerParam  = cmdReadBinary.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
    	SqlParameter OffsetParam  = cmdReadBinary.Parameters.Add("@Offset", SqlDbType.Int);
    	SqlParameter SizeParam  = cmdReadBinary.Parameters.Add("@Size", SqlDbType.Int);
    	SqlDataReader dr; 
    	System.IO.FileStream fs = new System.IO.FileStream(DestFilePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
    	int Offset= 0;
    	OffsetParam.Value = Offset;
    	Byte []Buffer = new Byte[BUFFER_LENGTH ];
    
    			
    	// Read buffer full of data and write to the file stream.
    			
    	do
    	{
    		PointerParam.Value = PointerOutParam.Value;
    				
    		// Calculate buffer size - may be less than BUFFER_LENGTH for last block.
    				
    		if( (Offset + BUFFER_LENGTH) >= System.Convert.ToInt32(LengthOutParam.Value)) 
    			SizeParam.Value = System.Convert.ToInt32(LengthOutParam.Value) - Offset;
    		else SizeParam.Value = BUFFER_LENGTH;
    				
    		dr = cmdReadBinary.ExecuteReader(CommandBehavior.SingleResult);
    		dr.Read();
    		dr.GetBytes(PictureCol, 0, Buffer, 0, System.Convert.ToInt32(SizeParam.Value));
    		dr.Close();
    		fs.Write(Buffer, 0, System.Convert.ToInt32(SizeParam.Value));
    		Offset += System.Convert.ToInt32(SizeParam.Value);
    		OffsetParam.Value = Offset;
    	}while(Offset < System.Convert.ToInt32(LengthOutParam.Value));
    
    	fs.Close();
    	cn.Close();
       }
       catch(SqlException ex)
       {
       MessageBox.Show (ex.Message);
       }
    }
    
    public void OleDbChunkBlob2File(string DestFilePath)
    {
       try
       {
    	int PictureCol= 0; // Position of picture column in DataReader.
    	int BUFFER_LENGTH = 32768;// Chunk size.
    	OleDbConnection cn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");
    			
    	// Make sure Photo is non-NULL and return TEXTPTR to it.
    		
    	OleDbCommand cmdGetPointer = new OleDbCommand("SELECT ?=TEXTPTR(Picture), ?=DataLength(Picture) FROM Categories WHERE CategoryName='Test'", cn);
    	OleDbParameter PointerOutParam =  cmdGetPointer.Parameters.Add("@Pointer", OleDbType.VarBinary, 100);
    	PointerOutParam.Direction = ParameterDirection.Output;
    	OleDbParameter LengthOutParam = cmdGetPointer.Parameters.Add("@Length", OleDbType.Integer);
    	LengthOutParam.Direction = ParameterDirection.Output;
    	cn.Open();
    	cmdGetPointer.ExecuteNonQuery();
    if(PointerOutParam.Value == DBNull.Value )
    	{
    		cn.Close();
    		// Add code to deal with NULL BLOB.
    		return;
    	}
    			
    	// Set up READTEXT command, parameters, and open BinaryReader.
    			
    	OleDbCommand cmdReadBinary = new OleDbCommand("READTEXT Categories.Picture ? ? ? HOLDLOCK", cn);
    	OleDbParameter PointerParam  = cmdReadBinary.Parameters.Add("@Pointer", OleDbType.Binary, 16);
    	OleDbParameter OffsetParam  = cmdReadBinary.Parameters.Add("@Offset", OleDbType.Integer);
    	OleDbParameter SizeParam  = cmdReadBinary.Parameters.Add("@Size", OleDbType.Integer);
    	OleDbDataReader dr;
    	System.IO.FileStream fs = new System.IO.FileStream(DestFilePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
    	int Offset= 0;
    	OffsetParam.Value = Offset;
    	Byte[] Buffer = new Byte[BUFFER_LENGTH];
    			
    	//Read buffer full of data and write to the file stream.
    			
    	do
    	{
    		PointerParam.Value = PointerOutParam.Value;
    				
    		// Calculate buffer size - may be less than BUFFER_LENGTH for last block.
    				
    		if((Offset + BUFFER_LENGTH) >= System.Convert.ToInt32(LengthOutParam.Value))
    			SizeParam.Value = System.Convert.ToInt32(LengthOutParam.Value) - Offset;
    		else SizeParam.Value = BUFFER_LENGTH;
    				
    		dr = cmdReadBinary.ExecuteReader(CommandBehavior.SingleResult);
    		dr.Read();
    		dr.GetBytes(PictureCol, 0, Buffer, 0, System.Convert.ToInt32(SizeParam.Value));
    		dr.Close();
    		fs.Write(Buffer, 0, System.Convert.ToInt32(SizeParam.Value));
    		Offset += System.Convert.ToInt32(SizeParam.Value);
    		OffsetParam.Value = Offset;
    	}while( Offset < System.Convert.ToInt32(LengthOutParam.Value));
    
    	fs.Close();
    	cn.Close();
       }
       catch(OleDbException ex)
       {
       MessageBox.Show (ex.Message);
       }
    }
    				
  11. Appuyez sur F5 pour exécuter le code, puis cliquez sur File2OleDbBlob pour vous assurer que vous charger une image dans la base de données SQL Server avant d'essayer d'écrire dans un fichier .bmp sur le disque.

Read chunks from a BLOB column

Les fonctions suivantes permet l'instruction SQL Server READTEXT et DataReader d'extraire une partie de la valeur BLOB d'une seule ligne, colonne simple ensemble de lignes. Deux commandes sont utilisées : le premier extrait de la taille du champ BLOB et un pointeur vers son emplacement ; le second s'exécute le READTEXT commande. La commande READTEXT récupère le bloc de données dans un tableau d'octets et incrémente un décalage. Le tableau d'octets est écrit sur le disque via le System.IO.Filesream objet.

Write chunks to a BLOB column

Les fonctions suivantes utiliser les objets Command et Parameter et l'instruction SQL Server UPDATETEXT pour écrire des blocs de données à partir d'un tableau d'octets à une colonne BLOB. La colonne BLOB ne peut pas être NULL avec cette méthode, un seul octet est affecté à la colonne avant TEXTPTR est extrait. Sur la première exécution de l'instruction UPDATETEXT DeleteParam.Value est défini sur 1. Cette supprime l'octet existant de la colonne avant d'insérer le bloc et d'empêche le BLOB des données superflues ajoutées à elle. L'instruction UPDATETEXT est exécuté plusieurs fois incrémenter le décalage de la taille du tampon après chaque appel. private
private void ChunkFile2SqlBlob(string SourceFilePath)
{
   try
   {
	int BUFFER_LENGTH = 32768; // Chunk size.
	SqlConnection cn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");
			
	// Make sure Photo is non-NULL and return TEXTPTR to it.
		
	SqlCommand cmdGetPointer = new SqlCommand("SET NOCOUNT ON;UPDATE Categories SET Picture = 0x0 WHERE CategoryName='Test';" +
					"SELECT @Pointer=TEXTPTR(Picture) FROM Categories WHERE CategoryName='Test'", cn);
	SqlParameter PointerOutParam  = cmdGetPointer.Parameters.Add("@Pointer", SqlDbType.VarBinary, 100);
	PointerOutParam.Direction = ParameterDirection.Output;
	cn.Open();
	cmdGetPointer.ExecuteNonQuery();
		
	// Set up UPDATETEXT command, parameters, and open BinaryReader.
			
	SqlCommand cmdUploadBinary = new SqlCommand("UPDATETEXT Categories.Picture @Pointer @Offset @Delete WITH LOG @Bytes", cn);
	SqlParameter PointerParam  = cmdUploadBinary.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
	SqlParameter OffsetParam= cmdUploadBinary.Parameters.Add("@Offset", SqlDbType.Int);
	SqlParameter DeleteParam = cmdUploadBinary.Parameters.Add("@Delete", SqlDbType.Int);
	DeleteParam.Value = 1;  // delete 0x0 character
				SqlParameter BytesParam  = cmdUploadBinary.Parameters.Add("@Bytes", SqlDbType.Binary, BUFFER_LENGTH);
	System.IO.FileStream fs = new System.IO.FileStream(SourceFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
	System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
	int Offset = 0;
	OffsetParam.Value = Offset;

			
	// Read buffer full of data and execute UPDATETEXT statement.
			
	Byte [] Buffer = br.ReadBytes(BUFFER_LENGTH);
	while(Buffer.Length > 0)
	{
		PointerParam.Value = PointerOutParam.Value;
		BytesParam.Value = Buffer;
		cmdUploadBinary.ExecuteNonQuery();
		DeleteParam.Value = 0; //Do not delete any other data.
		Offset += Buffer.Length;
		OffsetParam.Value = Offset;
		Buffer = br.ReadBytes(BUFFER_LENGTH);
	}

	br.Close();
	fs.Close();
	cn.Close();
   }
   catch(SqlException ex)
   {
   MessageBox.Show (ex.Message);
   }			
}

public void ChunkFile2OleDbBlob(string SourceFilePath)
{
   try
   {	
         int BUFFER_LENGTH = 32768; // chunk size
	OleDbConnection cn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;");
		
	// Make sure Photo is non-NULL and return TEXTPTR to it.
		
	OleDbCommand cmdGetPointer = new OleDbCommand("SET NOCOUNT ON;UPDATE Categories SET Picture = 0x0 WHERE CategoryName='Test';" +
				"SELECT ?=TEXTPTR(Picture) FROM Categories WHERE CategoryName='Test'", cn);
	OleDbParameter PointerOutParam = cmdGetPointer.Parameters.Add("@Pointer", OleDbType.VarBinary, 100);
	PointerOutParam.Direction = ParameterDirection.Output;
	cn.Open();
	cmdGetPointer.ExecuteNonQuery();
			
	// Set up UPDATETEXT command, parameters, and open BinaryReader.
			
	OleDbCommand cmdUploadBinary = new OleDbCommand("UPDATETEXT Categories.Picture ? ? ? WITH LOG ?", cn);
	OleDbParameter PointerParam = cmdUploadBinary.Parameters.Add("@Pointer", OleDbType.Binary, 16);
	OleDbParameter OffsetParam = cmdUploadBinary.Parameters.Add("@Offset", OleDbType.Integer);
	OleDbParameter DeleteParam   = cmdUploadBinary.Parameters.Add("@Delete", OleDbType.Integer);
	DeleteParam.Value = 1;  // delete 0x0 character
	OleDbParameter BytesParam = cmdUploadBinary.Parameters.Add("@Bytes", OleDbType.Binary, BUFFER_LENGTH);
	System.IO.FileStream fs = new System.IO.FileStream(SourceFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
	System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
	int Offset= 0;
	OffsetParam.Value = Offset;

			
	// Read buffer full of data and execute UPDATETEXT statement.
			
         Byte[] Buffer = br.ReadBytes(BUFFER_LENGTH);
	while(Buffer.Length > 0)
	{
		PointerParam.Value = PointerOutParam.Value;
		BytesParam.Value = Buffer;
		cmdUploadBinary.ExecuteNonQuery();
		DeleteParam.Value = 0;// Do not delete any other data.
		Offset += Buffer.Length;
		OffsetParam.Value = Offset;
		Buffer = br.ReadBytes(BUFFER_LENGTH);
	}

	br.Close();
	fs.Close();
	cn.Close();		
   }
   catch(OleDbException ex)
   {
   MessageBox.Show (ex.Message);
   }
}
				
notes
  • Le code qui est décrit dans cet article ne peut-être être utilisées contre LongVarChar ou LongVarWChar colonnes sans modification.
  • Vous devez modifier la chaîne de connexion et des instructions SQL pour correspondre aux votre propre serveur. Vous devez également ajouter si votre requête ne retourne aucun enregistrement de vérification des erreurs.
  • READTEXT et UPDATETEXT sont spécifiques à Microsoft SQL Server. Différents systèmes de base de données est peut-être commandes similaires que vous pouvez utiliser.

Références

Pour plus d'informations sur comment lire et écrire des données sans segmentation, cliquez sur les numéros ci-dessous pour afficher les articles correspondants dans la Base de connaissances Microsoft :
316887 Comment lire et écrire un fichier vers et depuis une colonne BLOB à l'aide de ADO.NET et Visual Basic .NET
317017 Comment lire et écrire un fichier vers et depuis une colonne BLOB à l'aide ADO.NET et Visual C++ .NET
317016 Comment lire et écrire un fichier vers ou à partir d'une colonne BLOB à l'aide ADO.NET et Visual C# .NET
Pour plus d'informations sur l'utilisation des données BLOB dans ADO.NET, reportez-vous au à l'adresse suivante du MSDN (Microsoft Developer Network) :
Obtention de valeurs BLOB à partir d'une base de données
http://msdn.microsoft.com/en-us/library/87z0hy49.aspx

Propriétés

Numéro d'article: 317043 - Dernière mise à jour: mercredi 27 octobre 2004 - Version: 3.3
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft ADO.NET (included with the .NET Framework)
  • Microsoft ADO.NET 1.1
  • Microsoft Visual C# .NET 2002 Initiation
  • Microsoft Visual C# .NET 2003 Initiation
Mots-clés : 
kbmt kbsystemdata kbsqlclient kbhowtomaster KB317043 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 317043
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com