Takusen:截断错误

时间:2011-03-09 20:40:56

标签: haskell

我写了一个小脚本,用Takusen从Oracle中提取数据:

{-# LANGUAGE ScopedTypeVariables #-}
module Test where

import Database.Oracle.Enumerator
import Control.Monad.Trans (liftIO)
import Connections (watDevDb, watProdDb)
import System.Environment
import Data.Char

main :: IO ()
main = do
  [fn] <- getArgs
  sqls <- readFile fn
  flip catchDB reportRethrow (withSession watProdDb $ do
         let iter (c1::Maybe String) (c2::Maybe String) (c3::Maybe String) (r::Maybe String) = result' c3
         rslt <- doQuery (sql sqls) iter (Nothing::Maybe String)
         liftIO (putStrLn . show $ rslt))

test = withArgs ["extract.sql"] main

c2c3是CLOB-s 当我尝试执行它时,我收到以下错误消息:

*** Exception: DBError ("01","000") 1406 " : ORA-01406: fetched column value was truncated\n"

事实证明c3是有问题的。当我从查询中排除它时,它工作得很好。 从错误判断,我需要增加c3的缓冲区大小以避免截断,但我在Takusen文档中找不到类似的东西。

任何帮助?

2 个答案:

答案 0 :(得分:2)

我联系了Takusen的作者并得到了以下回复(Oleg):

  

bindBuffer确实与手头的问题无关:bindBuffers   在将数据绑定到查询变量(即移动数据)时使用   进入数据库。来自数据库的数据的缓冲区分配是   在类DBType的实例中完成。有几个例子   在       ... / takusen /数据库/ ORACLE / Enumerator.lhs   对于列类型Maybe String,相关的是

     

instance DBType(Maybe String)查询ColumnBuffer在哪里    allocBufferFor _ q n = allocBuffer q(16000,oci_SQLT_CHR)n    fetchCol q buffer = bufferToString buffer

     

分配的缓冲区似乎是16000字节。也许这个数字   应该增加。

这个缓冲区的增加解决了我的问题。

非常感谢Oleg等人

答案 1 :(得分:1)

快速浏览takusen代码会显示一个硬编码常量: - (

来自:http://code.haskell.org/takusen/Database/Oracle/Enumerator.lhs

instance OracleBind String where
   -- FIXME  should these be withUTF8String{Len} ?
   bindWithValue v a = withCString v (\p -> a (castPtr p))
   bindWriteBuffer b s = withCStringLen s (\(p,l) -> 
     copyBytes (castPtr b) p (1+l))
   bindDataSize s = fromIntegral (length s)
   bindBufferSize _ = 32000
   bindType _ = oci_SQLT_CHR

但这很容易解决,或者如果OracleBind是导出的类

newtype SomeHugeString = SomeHugeString {getHugeString :: String}
instance OracleBind SomeHugeString where ...

按原样,我认为你必须只创建自己的/Oracle/Enumerator.lhs文件的分支。