【问题标题】:Using LiveCode to retrieve unicode data from SQL Server via ODBC使用 LiveCode 通过 ODBC 从 SQL Server 检索 unicode 数据
【发布时间】:2013-03-08 03:58:52
【问题描述】:

我在使用 LiveCode 时遇到了这个问题,但我不知道这是问题所在还是与 ODBC 驱动程序有关。

LiveCode 中内置的应用会定期通过 ODBC 连接到 SQL Server 数据库,以检索各种数据。

负责数据库的应用程序正在升级,作为其中的一部分,所有文本字段都将转换为 Unicode 文本字段。本质上,这意味着以前定义为 varchar 的字段现在定义为 nvarchar,而以前定义为 text 的字段现在定义为 ntext。 (顺便说一下,这是 SQL Server 2008。)

使用我们过去一直使用的查询,我们现在得到一个字符(字段中的第一个字符)而不是整个文本。我现在可以通过在选择查询中指定到 varchar 的转换来解决这个问题,例如应用程序用来发出请求的地方 选择 id,名称来自 tab1 它现在提出一个请求 SELECT id, convert(varchar(255), name) AS name FROM tab1

这行得通 - 我找回了以前得到的东西 - 但是(a)它很笨拙,并且(b)现在这很好,当客户只是将他们所有现有的数据迁移到数据库中时,但迟早他们实际上可能会利用这次升级在字段中输入一些 Unicode 字符,然后我大概不会把它们弄出来。

不幸的是,我无权访问数据库或应用程序来插入测试数据——但我假设这个问题会出现——而且很可能它不会很明显,即只会有一个微妙的问题我的应用程序没有处理输入的数据(但认为是)的问题。

那么:使用当前 ODBC 驱动程序的 LiveCode 应用程序是否可以从 nvarchar 或 ntext 字段中正确检索完整数据?

【问题讨论】:

  • 您目前使用什么代码从数据库中提取数据?
  • 查看下面对 Monte 的回答 - 真正使用 revdb_query、revdb_movenext 和 revdb_columnbynumber,但尝试使用 revQueryDatabase/revMoveToNextRecord/revDatabaseColumnNumbered 代替,结果相同(错误) 结果。在同一数据库上的测试应用程序中使用 revDataFromQuery 会检索完整数据,但不幸的是,在此应用程序中不是一个简单的选择。
  • 您是在使用 revDatabaseColumnNumbered() 的结果,还是在第三个参数中使用“持有者变量”?由于 UTF-16 是二进制数据,因此无法使用结果。

标签: sql-server unicode odbc livecode


【解决方案1】:

您是否可以使用 revDataFromQuery 而不是更强大的 revQueryDatabase?我不使用 revDataFromQuery 但我猜它使用的是不支持 UTF16 的 c 字符串函数。

【讨论】:

  • [对不起,违反了 SO 编辑限制] 实际上似乎相反。我现在已经使用通用 SQL 工具检索了示例数据(我没有对此数据库的交互式访问权限 - 可以将已编译的应用程序放在可以访问的盒子上)。为了回应您的评论,我检查了两个应用程序(都是我几年前写的):真正的应用程序,没有获取 Unicode 数据,使用 revdb_query/revdb_columnbynumber/revdb_movenext;而成功检索数据的混乱工具使用 revDataFromQuery。
  • 文档似乎对新功能和新名称有点困惑:revQueryDatabase 应该是revdb_query 的同义词,而revMoveToNextRecord 和revDatabaseColumnNumbered 被记录为好像新功能一样,与revdb_movenext 和revdb_columnbynumber 分开。 @Monte - 你似乎对内部有所了解 - 这是一个文档混淆,还是有可能虽然 revQueryDatabase 只是一个同义词,但同一套件的其他部分已经以更复杂的方式重新实现?跨度>
  • 我不知道内部结构。我正在猜测。两个应用中的查询是否相同?
  • SQL查询是一样的。我现在使用revQueryDatabase/revMoveToNextRecord/revDatabaseColumnNumbered 破解了我的应用程序的一个版本并运行了它——结果相同。所以目前的状态似乎是revDataFromQuery 有效,revQueryDatabase 无效。不幸的是,虽然我的测试查询只有几 K,但在生产使用中,结果可能 > 100MB - 而且这个应用程序在处理大数据之前遇到了内存问题 - 所以将代码转换为使用 revDataFromQuery 并非易事.
  • 你对 revDataFromQuery 之后的数据做了什么?就像您确定在获取数据后不会丢失数据一样。某些命令将在变量中为 null 后丢失所有内容。我知道至少 filter 会这样做,所以我猜可能还有其他人。
【解决方案2】:

嗯。取决于转换发生的位置。我不必处理这个问题,所以对它持保留态度...

如果整个 unicode 结果正在通过 odbc 驱动程序和 LiveCode 的 db 层,那么您应该能够对结果进行 unidecode。看起来您正在返回双字节字符,而第二个字节为零,如果字符串被视为单字节字符,它将以空值终止。正如您所指出的,这就是您在 SQL 请求中转换为 varchar 时发生的情况。

如果转换是在 odbc 层或 LC 的 db 层中进行的,那么在它成为开源并且可以重写以处理 unicode 之前你就很不走运了。

所以我想说不要转换为 varchar,在检查结果之前尝试对结果进行 unidecode,这样你就有很大的机会看到你所期望的。

【讨论】:

    【解决方案3】:

    因此,为了任何遇到此问题的人的利益:事实证明,如果我只阅读文档的正确部分,我应该知道的问题是我在简单模式下使用 revDatabaseColumnNumbered -

    put revDatabaseColumnNumbered(iConnID, iColNum) into tData
    

    ...但该模式只能返回文本,这实际上不是我们这里所拥有的,而是二进制数据。所以解决办法就是使用第二种模式,

    get revDatabaseColumnNumbered(iConnID, iColNum, "tData")
    

    ...此时我们获得了完整的 Unicode 数据,然后可以决定如何处理它。根本不是revQueryDatabase 代码路径的错误,只是我在使用revDatabaseColumnNumbered 时的错误。

    感谢所有试图帮助我的人!

    【讨论】:

      猜你喜欢
      • 2012-12-27
      • 1970-01-01
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-20
      相关资源
      最近更新 更多