我正在尝试使用GetChars方法从Oracle数据库查询中读取CLOB值。我这样做是为了能够缓冲非常大的CLOB值并将结果写入XML文件。
然而,似乎存在一个问题,即OracleDataReader的GetChars方法只缓冲它应该的一半字符。这导致我继续在循环中缓冲,直到GetChars返回0,但我认为这是非常低效的并且正在减慢我的程序。
有谁知道为什么会这样?这是我正在使用的代码片段:
Dim reader As Data.OracleClient.OracleDataReader
Dim bufferSize As Integer = 1024 * 2000
Dim outChar(bufferSize - 1) As Char
Using connection As New Data.OracleClient.OracleConnection(connectString)
Dim command As New Data.OracleClient.OracleCommand(statement)
command.Connection = connection
connection.Open()
reader = command.ExecuteReader(System.Data.CommandBehavior.SequentialAccess)
Do While reader.Read()
' Reset the starting char for a new CLOB
startIndex = 0
Array.Clear(outChar, 0, bufferSize)
' Read chars into outChar() and retain the number of bytes returned
retval = reader.GetChars(0, startIndex, outChar, 0, bufferSize)
Do Until retval = 0
rawStr = New String(outChar)
rawStr = rawStr.Replace(Chr(0), "")
myxml.WriteRaw(rawStr)
myxml.Flush()
startIndex += rawStr.Length
Array.Clear(outChar, 0, bufferSize)
retval = reader.GetChars(0, startIndex, outChar, 0, bufferSize)
Loop
Loop
End Using
答案 0 :(得分:0)
Microsoft已弃用System.Data.OracleClient
程序集/命名空间:
System.Data.OracleClient Namespace | MSDN:
System.Data.OracleClient中的类型已弃用,将在.NET Framework的未来版本中删除。
还有一个名为ODP.NET的Oracle新版本,它仍然受支持。有两个NuGet包可用:
您可能还想安装the developer tools。
如果您想坚持使用Microsoft库,可以尝试使用the GetOracleLob
method。这将返回an OracleLob
object,您可以使用它来读取值:
Using lob As OracleLob = reader.GetOracleLob(0)
Using sr As New StreamReader(lob, Text.Encoding.Unicode)
retval = sr.Read(outChar, 0, bufferSize)
Do Until retval = 0
myxml.WriteRaw(outChar, 0, retval)
myxml.Flush()
Array.Clear(outChar, 0, retval)
retval = sr.Read(outChar, 0, bufferSize)
Loop
End Using
End Using
您可能需要调整传递给StreamReader
构造函数的编码。 GetChars
方法默认使用Unicode,但我怀疑你的字符串可能采用不同的编码。
查看dotPeek中的代码,这比调用GetChars
更有效:
GetChars
方法会在每次调用时创建一个新的OracleLob
,并读取其Value
属性。Value
属性会在每次调用时将整个字符串读入内存。GetChars
方法将字符串复制到Char
数组。GetChars
方法将数组的指定部分复制到您传入的缓冲区。这是非常低效的,你的代码运行缓慢也就不足为奇了!