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

数据|数据库

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();

时间: 2024-09-09 02:20:24

数据库中取Clob类型字段出现乱码的相关文章

asp.net关于根据gridview中取到的值从数据库中读取image类型的图片信息并显示

问题描述 asp.net关于根据gridview中取到的值从数据库中读取image类型的图片信息并显示 前台代码 <asp:GridView ID=""GridView1"" runat=""server"" AutoGenerateColumns=""False"" GridLines=""Vertical"" OnRowCommand=&

clob-请问PHP如何读取Oracle数据库中的CLOB字段?

问题描述 请问PHP如何读取Oracle数据库中的CLOB字段? 请问PHP如何读取Oracle数据库中的CLOB字段?数据库中CLOB字段中是文本内容. 试了N多次,都没用,还望各位大神不吝赐教,感谢!

php数据库中取值-php+mysql 数据库中取值

问题描述 php+mysql 数据库中取值 php+mysql 数据库中取值 表中字段是int类型,1代表供货商发货,2代表公司配货 .在页面上用一个下拉列表选择发货方式,如何把 供货商发货 公司配货 字样显示在下拉列表中 , 提交表单后可以更改配货方式,,, 后台逻辑该怎么写呢? 解决方案 http://yuncode.net/code/c_5267eac94c46717 解决方案二: http://www.jb51.net/article/60189.htm

SQL查询语句中的bool类型字段值的写法

  SQL查询语句中的bool类型字段值的写法 没有系统地看过SQL语句的写法说明,只是看了一些常用SQL语句的例子.今天写了条select * from table where sex='true',老是提示标准数据类型不匹配(我用的Access),检查了半天,原来sex字段作为bool(是/否)类型,在SQL语句中其值不需要用''引起来.

postgresql-PostgreSQL 中的json类型字段查询

问题描述 PostgreSQL 中的json类型字段查询 PostgreSQL 中的json类型字段查询,该字段只有 '[]',就是空值,怎么查询是这些的数据 解决方案 这不是空值,是个空数组,判断该数组的 length为零即可.

安卓-为什么从数据库中取不出来东西呢

问题描述 为什么从数据库中取不出来东西呢 显示耗时程序不能在主线程中,然后我把while循环放在了一个子线程中运行但是活动直接蹦了,请问这是为什么啊,我已经确定数据库中有一条数据, 解决方案 后拉iwo用while(movetonext)循环来查数据,还是不行,然后我就新开了一个线程来做循环,然后就崩溃了

dropdownlist-如何将DropDownList中从数据库中取到的数据,显示到Label

问题描述 如何将DropDownList中从数据库中取到的数据,显示到Label 专家姓名: DataSourceID="SqlDataSource1" DataTextField="PF_Name" DataValueField="PF_Name" onselectedindexchanged="DropDownList1_SelectedIndexChanged">/asp:DropDownList 专家ID:/as

在mysql数据库中关于日期时间字段的处理

在mysql数据库中关于日期时间字段的处理 在开发中,日期时间字段一般有如下几种设计 假设要获取2013-08-15日到2013-08-16日之间的记录 1. 直接使用日期时间类字段 相关sql语句如下 select * from cms_news where  news_add_time between str_to_date("2013-08-15 00:00:00",'%Y-%m-%d %H:%i:%s') and str_to_date("2013-08-16 23:

我现在从数据库中取到值到Table,但是我想把第一列 地二列(全部相同)合并,怎么用for循环啊?

问题描述 请问大神,我现在从数据库中取到值到Table,但是我想把第一列地二列(全部相同)合并,怎么用for循环啊? 解决方案 解决方案二:第一列地二列(全部相同),这什么意思,合并又是什么意思,两列相加吗?解决方案三:select语句加DISTINCT解决方案四:我要是展示这样的的解决方案五:我这样循环前两列是对的,加上地三列地三个循环就不对了,求大神指教啦.拜谢.<tableborder="0"class="listtable"style="te