Como ler e gravar um arquivo para e de uma coluna BLOB usando o agrupamento no ADO.NET e Visual translation from VPE for Csharp .NET

Traduções deste artigo Traduções deste artigo
ID do artigo: 317043 - Exibir os produtos aos quais esse artigo se aplica.
Para uma versão deste artigo do Microsoft Visual Basic. NET, consulte 317034.
Para uma versão deste artigo do Microsoft Visual C++. NET, consulte 317044.
Expandir tudo | Recolher tudo

Neste artigo

Sumário

Este artigo passo a passo descreve como usar as instruções READTEXT do Microsoft SQL Server e UPDATETEXT para ler e gravar dados das colunas BLOB (LongVarBinary) em uma tabela de banco de dados.

Devido a restrições de rede, talvez você precise recuperar um arquivo BLOB grande em partes menores e, em seguida, peça as partes juntas em vez de recuperar BLOB todo arquivo de uma só vez. No entanto, os provedores de dados ADO.NET não tem métodos AppendChunk e GetChunk disponíveis para o Data Access Object (DAO) e objetos ActiveX Data Objects (ADO). Recordset . Este artigo descreve maneiras de recuperar dados em partes menores.

anotações :
  • Este artigo contém exemplos para dados SqlClient provedor e o OLE DB .NET Data Provider. As únicas diferenças, além de nomes de classe, são as seqüências de conexão e a declaração de parâmetros SQL. A técnica básica para recuperar as instruções READTEXT e UPDATETEXT é o mesmo.
  • O registro de teste na tabela Categorias do Northwind banco de dados de exemplo não existe. Você deve usar o Server Explorer ou outra ferramenta para adicionar um registro com o NomeDaCategoria definida como teste . Após usar os exemplos a seguir, convém remover esse registro do banco de dados. Para remover o registro, digite o seguinte comando no SQL Query Analyzer e, em seguida, pressione F5:
    use Northwind
    delete from Categories where CategoryName = 'Test'
    					

Requirements

Os seguintes itens descrevem recomendado de hardware, software, infra-estrutura de rede, habilidades e conhecimento e service packs são necessários:
  • Microsoft Windows 2000 Professional, Windows 2000 Server, o Windows 2000 Server ou Microsoft Windows NT 4.0 Server
  • Microsoft Visual Studio .NET
  • Microsoft SQL Server 7.0 ou posterior
Este artigo presume que você esteja familiarizado com o ADO.NET conceitos básicos e sintaxe.

Create a project and add code

  1. Abra o SQL Query Analyzer.
  2. Digite o seguinte comando e pressione F5 para alterar o banco de dados padrão para Northwind:
    use Northwind
  3. Digite o seguinte comando e pressione F5 para inserir um novo registro na tabela Categorias do banco de dados Northwind:
    Insert into categories(categoryname) values ('Test')
    Observação você só precisa adicionar este registro à tabela Categorias, se você quiser usar esse exemplo sem modificar os dados existentes nesta tabela.
  4. No Visual Studio. NET, criar um novo Visual translation from VPE for Csharp .NET Windows Application projeto.
  5. Athe parte superior do seu arquivo Form1.cs, adicione as duas seguintes linhas de código para adicionar referências para o projeto para System.Data.SQLClient e System.Data.OLEDB :
    using System.Data.SqlClient;
    using System.Data.OleDb;
  6. Adicione quatro botões ao Form1. Altere a propriedade Text dos botões para SQLBlob2File , OlDbBlob2File , File2OleDbBlob e File2SqlBlob , respectivamente.
  7. Adicionar as seguintes declarações de variável de seqüência de caracteres sob a classe pública Form1:
    string destfilepath;
    string sourcefilepath;
    					
  8. Cole o seguinte código no evento de carregar formulário:
    destfilepath = @"c:\mytest.bmp";
    sourcefilepath = @"c:\windows\coffee bean.bmp";
    					
  9. Chamar os procedimentos no evento Click para cada botão:
    // 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. Colar quatro funções a seguir no 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. Pressione F5 para executar o código e, em seguida, clique em File2OleDbBlob para certificar-se que você carregar uma imagem no banco de dados do SQL Server antes de tentar gravar em um arquivo .bmp no disco.

Read chunks from a BLOB column

As seguintes funções usarem a instrução SQL Server READTEXT e DataReader para recuperar uma parte do valor BLOB em um conjunto de registros único linha e coluna única. Dois comandos são usados: o primeiro recupera o tamanho do campo BLOB e um ponteiro para seu local; a segunda executa o READTEXT comando. O comando READTEXT recupera o bloco de dados em uma matriz byte e incrementa um deslocamento. A matriz de bytes é gravada no disco por meio de System.IO.Filesream objeto

Write chunks to a BLOB column

As seguintes funções usarem os objetos de comando e parâmetro e a instrução SQL Server UPDATETEXT para gravar blocos de dados de uma matriz de byte para uma coluna BLOB. A coluna BLOB não pode ser NULL com esse método, portanto, um único byte é atribuído para a coluna antes TEXTPTR é recuperado. Na primeira execução da instrução UPDATETEXT, DeleteParam.Value é definido como 1. Isso exclui o byte existente da coluna antes de inserir o bloco e impede que o BLOB ter dados irrelevantes acrescentados. A instrução UPDATETEXT é executada várias vezes, incrementando o deslocamento com o tamanho do buffer após cada chamada.
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);
   }
}
				
anotações
  • O código que é descrito neste artigo pode não ser adequado para uso contra LongVarChar ou LongVarWChar colunas sem modificação.
  • Você deve modificar a seqüência de caracteres de conexão e instruções SQL para corresponder ao seu próprio servidor. Você também deve adicionar verificação se sua consulta não retorna nenhum registro de erros.
  • READTEXT e UPDATETEXT são específicas para Microsoft SQL Server. Sistemas de banco de dados diferente podem ter semelhantes comandos que você pode usar.

Referências

Para informações adicionais sobre como ler e gravar dados sem agrupamento, clique nos números abaixo para ler os artigos na Base de dados de Conhecimento da Microsoft:
316887Como ler e gravar um arquivo para e de uma coluna BLOB usando ADO.NET e Visual Basic .NET
317017Como ler e gravar um arquivo para e de uma coluna BLOB usando ADO.NET e Visual C++ .NET
317016Como ler e gravar um arquivo ou de uma coluna BLOB usando ADO.NET e Visual translation from VPE for Csharp .NET
Para obter mais informações sobre como trabalhar com BLOBs no ADO.NET, visite o seguinte site da Web Microsoft Developer Network (MSDN):
Obtendo valores BLOB de um banco de dados
http://msdn.microsoft.com/en-us/library/87z0hy49.aspx

Propriedades

ID do artigo: 317043 - Última revisão: quarta-feira, 27 de outubro de 2004 - Revisão: 3.3
A informação contida neste artigo aplica-se a:
  • 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
Palavras-chave: 
kbmt kbsystemdata kbsqlclient kbhowtomaster KB317043 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 317043

Submeter comentários

 

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