ODBC 中的 Haskell Unicode 列名

标签 haskell unicode odbc hdbc

我正在尝试通过 HDBC 从 MSSQL 数据库查询一些数据和 ODBC 。然而,当我尝试从列名称中包含 unicode 的表中查询数据时,我遇到了问题。

考虑以下 MWE:

mwe :: IConnection conn => conn -> IO [[SqlValue]]
mwe conn =
  do r <- quickQuery' conn
          "SELECT [Højde] FROM [Table]"
          []
     return r

当执行上述代码并将其传递给数据库的连接对象时,我收到以下错误消息:

*** Exception: SqlError {seState = "[\"42S22\",\"42000\"]", seNativeError = -1, seErrorMsg = "execute execute: [\"207: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name 'H\\195\\184jde'.\",\"8180: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Statement(s) could not be prepared.\"]"}

相关部分很可能是 H\\195\\184jde 不是有效的列名称。

我的研究主要得出了有关查询参数中 unicode 的结果。我尝试使用字节串而不是普通字符串,但由于 QuickQuery' 的参数是一个没有帮助的字符串。

最佳答案

我没有 MS SQL 实例来测试这一点,但是 code HDBC-odbc 使用 UTF-8 对查询进行编码。同时,this documentation建议对于现代 ODBC 驱动程序,用于查询的字符集取决于驱动程序初始化时的进程区域设置。如果它是 "C"(这是通常的进程默认值),则驱动程序将使用 UTF-8 字符集。但是,如果该进程执行:

setlocale(LC_ALL,"")

在初始化驱动程序之前,并且当前的 Windows 区域设置是使用 Latin-1 1252 代码页的英语,那么 ODBC 驱动程序将需要 Latin-1 编码的查询。不幸的是,GHC 运行时确实运行 setlocale(LC_ALL,""),所以这可能就是出了问题的地方。

如果您在 “main” 开头将语言环境重置为 “C”,则可能会解决该问题:

{-# LANGUAGE ForeignFunctionInterface #-}

import Control.Monad
import Foreign.C
import Foreign.Ptr

foreign import ccall "locale.h setlocale" c_setlocale :: CInt -> CString -> IO CString

setCLocale :: IO ()
setCLocale = do
  rc <- withCString "C" $ c_setlocale 0
  when (rc == nullPtr) $ error "setCLocale failed"

main = do
  setCLocale
  print "whatever"

我不确定这是否会导致其他问题(例如,终端输入/输出)。如果是这样,您可以在初始化驱动程序之前将区域设置设置为 "C",然后立即将其重置为 ""

关于ODBC 中的 Haskell Unicode 列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60617566/

相关文章:

c - fopen 不能在 linux 中为名称中包含德语字符的文件工作

database - 像这样解决数据库连接错误: [ISQL]ERROR: Could not SQLConnect

function - 根据类型为泛型函数提供不同的函数体

haskell - 理解 Haskell 序列

haskell - 将 llvm-general-pure AST 漂亮地打印为 llvm-ir?

c# - 使用参数和只放置一个变量然后转换它有什么区别

c++ - 长度超过 255 字节的字符串可以用作 ODBC 准备语句参数值吗?

haskell - 约束子集高阶约束

xcode - 在 Xcode 的 UILabel 中显示货币符号

java - 编写没有 BOM 的 UTF-8