OracleDataReader GetChars方法只缓冲一半字符

时间:2015-07-21 15:45:54

标签: vb.net oracle

我正在尝试使用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

1 个答案:

答案 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更有效:

  1. GetChars方法会在每次调用时创建一个新的OracleLob,并读取其Value属性。
  2. Value属性会在每次调用时将整个字符串读入内存。
  3. 然后GetChars方法将字符串复制到Char数组。
  4. 然后GetChars方法将数组的指定部分复制到您传入的缓冲区。
  5. 这是非常低效的,你的代码运行缓慢也就不足为奇了!

    the discussion thread on CodeProject交叉发布。