읽기 및 ADO.NET과 VISUAL C#에서 청크를 사용 하 여 BLOB 열 간에 파일을 작성 하는 방법

이 문서의 Microsoft Visual Basic.NET 버전을 참조 하십시오.
317034 .
이 문서의 Microsoft Visual C++.NET 버전을 참조 하십시오.
317044 .

요약

이 문서를 읽고 데이터베이스 테이블에서 BLOB (LongVarBinary) 열에서 데이터를 쓰는 READTEXT Microsoft SQL Server 및 UPDATETEXT 문을 사용 하는 방법을 설명 합니다.

네트워크 제약 조건 때문에 큰 BLOB 파일을 작은 청크로 검색할 및 청크 함께 전체 BLOB 파일을 한 번에 검색 하는 대신 다음 정보 해야 할 수 있습니다. 그러나 ADO.NET 데이터 공급자는 데이터 액세스 개체 (DAO)와 ActiveX 데이터 개체 (ADO) Recordset 개체에 사용할 수 있는 현재GetChunk 메서드를 갖지 않습니다. 더 작은 청크에서 데이터를 검색 하는 다른 방법을 설명 합니다.

참고 사항:
  • SqlClient 데이터 공급자와 OLE DB.NET 데이터 공급자에 대 한 예제가 나와 있습니다. 클래스 이름 별도로 유일한 차이점, 연결 문자열과 SQL 매개 변수의 선언 됩니다. UPDATETEXT 및 READTEXT 문을 검색 하는 기본 방법은 같습니다.
  • Northwind 예제 데이터베이스의 범주 테이블의 테스트 레코드가 존재 하지 않습니다. 서버 탐색기를 사용 해야 하거나 범주 를 사용 하 여 레코드를 추가할 수 있는 기능도 테스트로 설정 합니다. 다음 예제를 사용 하면 데이터베이스에서이 레코드를 제거 하는 것이 좋습니다. 레코드를 제거 하려면 SQL 쿼리 분석기에서 다음 명령을 입력 한 다음 F5 키를 누릅니다.
    use Northwinddelete from Categories where CategoryName = 'Test'

맨 위로

요구 사항

다음 항목은 권장 되는 하드웨어, 소프트웨어, 네트워크 인프라, 기술과 지식 및 필요한 서비스 팩 설명입니다.
  • Microsoft Windows 2000 Professional, Windows 2000 Server, Windows 2000 고급 서버 또는 Microsoft Windows NT 4.0 서버
  • Microsoft Visual Studio.NET
  • Microsoft SQL Server 7.0 이상
이 문서는 ADO.NET 기본 사항 및 구문에 익숙한 가정 합니다.

맨 위로

프로젝트 만들기 및 코드 추가

  1. SQL 쿼리 분석기를 엽니다.
  2. 다음 명령을 입력 하 고 f5 키를 눌러 Northwind를 기본 데이터베이스를 변경 합니다.
    use Northwind
  3. 다음 명령을 입력 하 고 f5 키를 눌러 Northwind 데이터베이스의 Categories 테이블에 새 레코드를 삽입 합니다.
    Insert into categories(categoryname) values ('Test')
    참고: 이 예제에서는이 테이블의 기존 데이터를 수정 하지 않고 사용할 경우 Categories 테이블에이 레코드를 추가 하기만 하면 됩니다.
  4. Visual Studio.NET에서 새 Visual C#.NET Windows 응용 프로그램 프로젝트를 만듭니다.
  5. Form1.cs 파일을 사용자별 맨 System.Data.OleDb설정 에 대 한 참조를 프로젝트에 추가 하는 코드는 다음 두 줄을 추가 합니다.
    using System.Data.SqlClient;using System.Data.OleDb;
  6. Form1에 단추 4 개를 추가 합니다. 각각 SQLBlob2File, OlDbBlob2File, File2OleDbBlobFile2SqlBlob단추의 Text 속성을 변경 합니다.
  7. Form1 공용 클래스에서 다음 문자열 변수 선언을 추가 합니다.
    string destfilepath;string sourcefilepath;

  8. 폼의 Load 이벤트가 아래에 다음 코드를 붙여 넣습니다.
    destfilepath = @"c:\mytest.bmp";sourcefilepath = @"c:\windows\coffee bean.bmp";

  9. 각 단추에 대해 Click 이벤트 프로시저를 호출 합니다.
    // 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. 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. F5 키를 눌러 코드를 실행 한 다음 클릭
    File2OleDbBlob .bmp 파일로 디스크에 기록 하기 전에 SQL Server 데이터베이스에서 이미지를 로드 해야 합니다.
맨 위로

BLOB 열에서 읽기 청크

다음 함수는 단일 행, 단일 열 행 집합에 BLOB 값의 일부를 검색할 SQL Server READTEXT 문 및 DataReader를 사용. 두 개의 명령이 사용 됩니다: 크기 BLOB 필드 및 해당 위치에 대 한 포인터를 검색 하는 첫 번째 두 번째는 READTEXT 명령을 실행합니다. READTEXT 명령 바이트 배열의 데이터 청크를 검색 하 고 오프셋 증가 시킵니다. 바이트 배열은 System.IO.Filesream 개체를 통해 디스크에 기록 됩니다. 맨 위로

BLOB 열에 청크를 작성 합니다.

다음 함수는 명령매개 변수 개체 및 SQL Server의 UPDATETEXT 문을 사용 하 여 BLOB 열에 바이트 배열의 데이터 청크를 작성. BLOB 열 TEXTPTR 검색 되기 전에 단일 바이트 열에 지정 되어 있으므로이 메서드를 사용 하 여 NULL 일 수 없습니다. UPDATETEXT 문의 첫 번째 실행에서 DeleteParam.Value 를 1로 설정 됩니다. 이 기존 바이트 열에서 해당 청크를 삽입 하기 전에 삭제 하 고 BLOB 불필요 한 데이터를 추가 하는 것을 금지 합니다. UPDATETEXT 문이 실행 된 여러 번 각 호출 후 오프셋 버퍼 크기를 사용 하 여 증가입니다.
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);
}
}

참고
  • 이 문서에서 설명 하는 코드를 수정 하지 않고 LongVarChar 또는 LongVarWChar 열에 대해 사용 하기에 적합 수 있습니다.
  • 연결 문자열과 SQL 문을 직접 서버에 맞게 수정 해야 합니다. 오류 검사 쿼리에서 레코드가 반환 되는 경우 추가 해야 합니다.
  • UPDATETEXT 및 READTEXT에는 Microsoft SQL Server 적용 됩니다. 다른 데이터베이스 시스템은 비슷한 명령을 사용할 수 있는 있을 수 있습니다.
맨 위로

참조

읽거나 쓰고 데이터 청크 없이 방법에 대 한 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조 하는 다음 문서 번호를 클릭 합니다.

316887 읽고 BLOB 열 간에 ADO.NET과 Visual Basic.NET을 사용 하 여 파일을 작성 하는 방법

317017 읽고 BLOB 열 간에 ADO.NET과 Visual C++.NET을 사용 하 여 파일을 작성 하는 방법

317016 읽고 ADO.NET과 Visual C#.NET을 사용 하 여 BLOB 열 간에 파일을 쓰는 방법

Blob을 ADO.NET 사용 하는 방법에 대 한 자세한 내용은 다음 Microsoft Developer Network (MSDN) 웹 사이트를 방문 하십시오.
데이터베이스에서 BLOB 값 가져오기
http://msdn.microsoft.com/en-us/library/87z0hy49.aspx
맨 위로
속성

문서 ID: 317043 - 마지막 검토: 2017. 2. 7. - 수정: 1

피드백