Jak číst a zapisovat do souboru z sloupce BLOB a pomocí bloků v ADO.NET a Visual C# .NET

Překlady článku Překlady článku
ID článku: 317043 - Produkty, které se vztahují k tomuto článku.
Microsoft Visual Basic .NET verzi tohoto článku naleznete 317034.
Microsoft Visual C++ .NET verzi tohoto článku naleznete 317044.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

Souhrn

Tento podrobný článek popisuje způsob použití příkazů Microsoft SQL Server READTEXT a UPDATETEXT číst a zapisovat data ze sloupců BLOB (LongVarBinary) v tabulce databáze.

Z důvodu omezení sítě může mít načtení velkého souboru BLOB v menší bloky a poté kámen bloky společně namísto celé BLOB načítání souboru najednou. Zprostředkovatelé dat ADO.NET nemají GetChunkAppendChunk metod a k dispozici Data Access Object (DAO) a objekty Objects (ADO) ADO Recordset. Tento článek popisuje různé způsoby načtení dat menší bloky.

Poznámky:
  • Tento článek obsahuje příklady SqlClient Data Provider a OLE DB zprostředkovatele dat .NET. Pouze rozdíly odlišuje od názvy tříd jsou řetězce připojení a deklarace parametry SQL. Základní techniky načíst příkazy READTEXT a UPDATETEXT je stejný.
  • Test záznam v tabulce kategorie neexistuje ukázkové databáze Northwind. Musíte použít Server Explorer nebo jiný nástroj Přidat záznam s NázevKategorie nastavit Test. Po použití následující ukázky můžete odebrat tento záznam z databáze. Odebrat záznam, zadejte následující příkaz SQL Query Analyzer a stiskněte klávesu F5:
    use Northwind
    delete from Categories where CategoryName = 'Test'
    					

Requirements

Následující položky popisují doporučený hardware, software, síťovou infrastrukturu, dovednosti a znalostní a požadované aktualizace service Pack:
  • Microsoft Windows 2000 Professional, Windows 2000 Server Windows 2000 Advanced Server nebo Microsoft Windows NT 4.0 Server
  • Microsoft Visual Studio .NET
  • Microsoft SQL Server 7.0 nebo vyšší
Tento článek předpokládá, že jste obeznámeni s ADO.NET základy a syntaxi.

Create a project and add code

  1. Spusťte nástroj SQL Query Analyzer.
  2. Zadejte následující příkaz a stiskněte klávesu F5 změnit výchozí databázi Northwind:
    use Northwind
  3. Zadejte následující příkaz a stiskněte klávesu F5 vložit nový záznam v tabulce Kategorie databázi Northwind:
    Insert into categories(categoryname) values ('Test')
    Poznámka máte přidat tento záznam do tabulky kategorie, pokud chcete použít tento příklad bez úpravou libovolné existující data v této tabulce.
  4. V aplikaci Visual Studio .NET vytvářet nové Visual C# .NET Windows Application projektu.
  5. Přidat následující dva řádky kódu přidat odkazy do projektu pro System.Data.SQLClient a System.data.OLEDB horní Athe souboru Form1.cs:
    using System.Data.SqlClient;
    using System.Data.OleDb;
  6. Přidat čtyři tlačítka Form1. Vlastnost text tlačítka změnit respektive SQLBlob2File, OlDbBlob2File, File2OleDbBlob a File2SqlBlob.
  7. Přidat následující proměnné deklarace řetězce ve třídě veřejné Form1:
    string destfilepath;
    string sourcefilepath;
    					
  8. Vložte následující kód ve skupinovém rámečku události Load formuláře:
    destfilepath = @"c:\mytest.bmp";
    sourcefilepath = @"c:\windows\coffee bean.bmp";
    					
  9. Volání procedury v události Click pro každé tlačítko:
    // 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);
    					
  10. Vložit následující čtyři funkce 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. Stisknutím klávesy F5 spustit kód a potom klepněte na tlačítko File2OleDbBlob zkontrolujte načíst obrázek v databázi SQL Server, než se pokusíte zapsat soubor BMP na disku.

Read chunks from a BLOB column

Následující funkce pomocí příkazu SQL Server READTEXT a objektu DataReader načíst část hodnoty BLOB v sadě řádků jediný řádek, jeden sloupec. Jsou použity dva příkazy: velikost pole BLOB a ukazatel na jeho umístění načte první; druhý provede READTEXT příkazu. Příkaz READTEXT načte bloku dat Byte matice a zvýší posunutí. Matice Byte zapsány na disk prostřednictvím System.IO.Filesream objektu.

Write chunks to a BLOB column

Následující funkce zápisu bloky dat z matice Byte sloupce BLOB pomocí objektů příkazů a parametrů a prohlášení SQL Server UPDATETEXT. Sloupce BLOB nesmí být NULOVÉ touto metodou tak jednoho bajtu je přiřazen do sloupce, před načtena TEXTPTR. Na první spuštění příkazu UPDATETEXT DeleteParam.Value nastavit na 1. Toto odstraní existující bajt před vložením bloku dat ze sloupce a zabrání nutnosti nadbytečné data připojena k jej BLOB. UPDATETEXT prohlášení je spuštěný více časy postupně po jednotlivých volání offset s velikost vyrovnávací paměti. soukromé
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);
   }
}
				
Poznámky
  • Kód popsané v tomto článku pravděpodobně nejsou vhodné pro použití v LongVarChar nebo LongVarWChar sloupců bez úprav.
  • Je třeba upravit připojovací řetězec a příkazů SQL odpovídat vlastní server. Musíte také přidat chyba kontrola Pokud dotaz vrátí žádné záznamy.
  • READTEXT a UPDATETEXT jsou specifické pro Microsoft SQL Server. Systémy jiné databáze může mít podobné příkazy, které můžete použít.

Odkazy

Další informace o čtení a zápisu dat bez bloků klepněte na následující čísla následujících článcích databáze Microsoft Knowledge Base:
316887Jak číst a zapisovat do souboru pomocí ADO.NET a Visual Basic .NET a ze sloupce BLOB
317017Jak číst a zapisovat do souboru z sloupce BLOB a pomocí ADO.NET a Visual C++ .NET
317016Jak číst a zapisovat do souboru nebo ze sloupce BLOB pomocí ADO.NET a Visual C# .NET
Další informace o práci s objekty BLOB ADO.NET na webu Microsoft Developer Network (MSDN):
Získání BLOB hodnoty z databáze
http://msdn.microsoft.com/en-us/library/87z0hy49.aspx

Vlastnosti

ID článku: 317043 - Poslední aktualizace: 27. října 2004 - Revize: 3.3
Informace v tomto článku jsou určeny pro produkt:
  • Microsoft ADO.NET (included with the .NET Framework)
  • Microsoft ADO.NET 1.1
  • Microsoft Visual C# .NET 2002 Standard Edition
  • Microsoft Visual C# .NET 2003 Standard Edition
Klíčová slova: 
kbmt kbsystemdata kbsqlclient kbhowtomaster KB317043 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:317043

Dejte nám zpětnou vazbu

 

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