数据库中取Clob类型字段出现乱码

原创 2004年09月17日 16:18:00

DataReader 的默认行为是在整个数据行可用时立即以行的形式加载传入数据。但是,对于二进制大对象 (BLOB) 则需要进行不同的处理,因为它们可能包含数十亿字节的数据,而单个行中无法包含如此多的数据。Command.ExecuteReader 方法具有一个重载,它将采用 CommandBehavior 参数来修改 DataReader 的默认行为。您可以将 CommandBehavior.SequentialAccess 传递到 ExecuteReader 方法来修改 DataReader 的默认行为,以便让 DataReader 按照顺序在接收到数据时立即将其加载,而不是加载数据行。这是加载 BLOB 或其他大数据结构的理想方案。请注意,该行为可能会因数据源的不同而不同。例如,从 Microsoft Access 中返回 BLOB 将导致整个 BLOB 加载到内存中,而不是按接收数据的顺序加载数据。

在将 DataReader 设置为使用 SequentialAccess 时,务必要注意访问所返回字段的顺序。DataReader 的默认行为是在整个行可用时立即加载该行,这使您能够在读取下一行之前按任何顺序访问所返回的字段。但是,当使用 SequentialAccess 时,必须按顺序访问由 DataReader 返回的不同字段。例如,如果查询返回三个列,其中第三列是 BLOB,则必须在访问第三个字段中的 BLOB 数据之前返回第一个和第二个字段的值。如果在访问第一个或第二个字段之前访问第三个字段,则第一个和第二个字段值将不再可用。这是因为 SequentialAccess 已修改 DataReader,使其按顺序返回数据,当 DataReader 已经读取超过特定数据时,该数据将不可用。

在访问 BLOB 字段中的数据时,请使用 DataReader 的 GetBytes 或 GetChars 类型化访问器,它们将用数据来填充数组。还可以对字符数据使用 GetString,但是为了节省系统资源,您可能不希望将整个 BLOB 值加载到单个字符串变量中。您可以指定要返回的特定数据缓冲区大小,以及从返回的数据中读取的第一个字节或字符的起始位置。GetBytes 和 GetChars 将返回一个 long 值,它表示返回的字节或字符数。如果将一个空数组传递给 GetBytes 或 GetChars,则返回的长值将是 BLOB 中字符或字符的总数。您可以选择将数组中的某个索引指定为所读取数据的起始位置。

以下示例从 Microsoft SQL Server 中的 pubs 示例数据库中返回发行者 ID 和徽标。发行者 ID (pub_id) 是字符字段,而徽标则是图形,即 BLOB。由于 logo 字段是位图,因此该示例使用 GetBytes 返回二进制数据。请注意,由于必须按顺序访问字段,所以将在访问徽标之前访问当前数据行的发行者 ID。

[Visual Basic]
Dim pubsConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;")
Dim logoCMD As SqlCommand = New SqlCommand("SELECT pub_id, logo FROM pub_info", pubsConn)

Dim fs As FileStream                 ' Writes the BLOB to a file (*.bmp).
Dim bw As BinaryWriter               ' Streams the binary data to the FileStream object.

Dim bufferSize As Integer = 100      ' The size of the BLOB buffer.
Dim outbyte(bufferSize - 1) As Byte  ' The BLOB byte() buffer to be filled by GetBytes.
Dim retval As Long                   ' The bytes returned from GetBytes.
Dim startIndex As Long = 0           ' The starting position in the BLOB output.

Dim pub_id As String = ""            ' The publisher id to use in the file name.

' Open the connection and read data into the DataReader.
pubsConn.Open()
Dim myReader As SqlDataReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAccess)

Do While myReader.Read()
  ' Get the publisher id, which must occur before getting the logo.
  pub_id = myReader.GetString(0)

  ' Create a file to hold the output.
  fs = New FileStream("logo" & pub_id & ".bmp", FileMode.OpenOrCreate, FileAccess.Write)
  bw = New BinaryWriter(fs)

  ' Reset the starting byte for a new BLOB.
  startIndex = 0

  ' Read bytes into outbyte() and retain the number of bytes returned.
  retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize)

  ' Continue reading and writing while there are bytes beyond the size of the buffer.
  Do While retval = bufferSize
    bw.Write(outbyte)
    bw.Flush()

    ' Reposition the start index to the end of the last buffer and fill the buffer.
    startIndex += bufferSize
    retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize)
  Loop

  ' Write the remaining buffer.
  bw.Write(outbyte, 0 , retval - 1)
  bw.Flush()

  ' Close the output file.
  bw.Close()
  fs.Close()
Loop

' Close the reader and the connection.
myReader.Close()
pubsConn.Close()

[C#]
SqlConnection pubsConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;");
SqlCommand logoCMD = new SqlCommand("SELECT pub_id, logo FROM pub_info", pubsConn);

FileStream fs;                          // Writes the BLOB to a file (*.bmp).
BinaryWriter bw;                        // Streams the BLOB to the FileStream object.

int bufferSize = 100;                   // Size of the BLOB buffer.
byte[] outbyte = new byte[bufferSize];  // The BLOB byte[] buffer to be filled by GetBytes.
long retval;                            // The bytes returned from GetBytes.
long startIndex = 0;                    // The starting position in the BLOB output.

string pub_id = "";                     // The publisher id to use in the file name.

// Open the connection and read data into the DataReader.
pubsConn.Open();
SqlDataReader myReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAccess);

while (myReader.Read())
{
  // Get the publisher id, which must occur before getting the logo.
  pub_id = myReader.GetString(0); 

  // Create a file to hold the output.
  fs = new FileStream("logo" + pub_id + ".bmp", FileMode.OpenOrCreate, FileAccess.Write);
  bw = new BinaryWriter(fs);

  // Reset the starting byte for the new BLOB.
  startIndex = 0;

  // Read the bytes into outbyte[] and retain the number of bytes returned.
  retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);

  // Continue reading and writing while there are bytes beyond the size of the buffer.
  while (retval == bufferSize)
  {
    bw.Write(outbyte);
    bw.Flush();

    // Reposition the start index to the end of the last buffer and fill the buffer.
    startIndex += bufferSize;
    retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);
  }

  // Write the remaining buffer.
  bw.Write(outbyte, 0, (int)retval - 1);
  bw.Flush();

  // Close the output file.
  bw.Close();
  fs.Close();
}

// Close the reader and the connection.
myReader.Close();
pubsConn.Close();

解决mybatis获取mysql blob 乱码问题

package cn.ffcs.drive.common.util; import java.io.ByteArrayInputStream; import java.io.Unsuppo...
  • p793049488
  • p793049488
  • 2014年07月15日 16:38
  • 9072

Mybatis大字段clob处理

1. 实体类View package com.ttt.sysManager.po; public class View { private String VIEW_NAME; private ...
  • gongzi2311
  • gongzi2311
  • 2015年10月12日 14:43
  • 12880

C#读取Clob数据并转换为字符串

C#读取Clob数据并转换为字符串:using System.Data.OracleClient;using System.IO;using System.Text;        int actua...
  • longronglin
  • longronglin
  • 2007年05月08日 20:53
  • 6035

使用 hibernate 存取大对象数据类型(clob和blob)

数据库表如下: book表 id 该表的主键。number类型。 photo 代表图书的图片,blob类型。 descripti...
  • z69183787
  • z69183787
  • 2013年11月22日 13:19
  • 17059

Java中读取Oracle中Clob字段的两种方法

第一种:import java.io.BufferedInputStream;import java.io.IOException;import java.sql.Clob;import java.s...
  • xianbin
  • xianbin
  • 2006年06月13日 15:59
  • 5454

java 读取clob字段的几种方法

最近频繁处理clob字段,故集中了几种读取clob字段的方法,供大家参考。     第一种:     Clob clob = rs.getClob("remark");//java.sql...
  • u010599762
  • u010599762
  • 2014年10月29日 17:52
  • 2742

mybatis查询出来的字段的值为null,驼峰字段

mybatis查询出来的数据为null,驼峰字段 昨天遇到奇葩问题。 开发环境一直好好的。 到了测试环境,就是流程跑不通。 3个伙伴排查了3个小时。 终于定位到问题的地方。 数据库...
  • yueguanyun
  • yueguanyun
  • 2017年09月14日 11:04
  • 609

Mybatis like 模糊查询问题

转载自:http://elang0705.iteye.com/blog/1700796 大家好,我只是IT行业的一只菜鸟,最近做的项目要求用Mybatis技术,在做一个模糊查询的时候,遇到点麻烦...
  • l2tp1012
  • l2tp1012
  • 2014年06月21日 09:56
  • 22384

MyBatis入门实例-包括实体类与数据库字段对应&CLOB字段处理

声明:本文大部分参考@孤傲苍狼的文章点击打开链接,在这之中加入了一些我的个人总结 1、我的开发环境是 jdk1.7+ecplise+oracle 11g      用到的jar包:mybatis-3....
  • SinsiWoo
  • SinsiWoo
  • 2016年09月22日 11:09
  • 5354

数据库中取Clob类型字段出现乱码

DataReader 的默认行为是在整个数据行可用时立即以行的形式加载传入数据。但是,对于二进制大对象 (BLOB) 则需要进行不同的处理,因为它们可能包含数十亿字节的数据,而单个行中无法包含如此多的...
  • luoboqingcai
  • luoboqingcai
  • 2004年09月27日 17:23
  • 760
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据库中取Clob类型字段出现乱码
举报原因:
原因补充:

(最多只允许输入30个字)