【问题标题】:How to retrieve a very long XML-string from an SQL database with R?如何使用 R 从 SQL 数据库中检索很长的 XML 字符串?
【发布时间】:2012-11-23 08:43:33
【问题描述】:

我有一个从 SQL 数据库获取 XML 文件的脚本。我是这样做的:

library(RODBC)
library(XML)

myconn <- odbcConnect("mydsn")

query.text <- "SELECT xmlfield FROM db WHERE id = 12345"
doc <- sqlQuery(myconn, query.text, stringsAsFactors=FALSE)
doc <- iconv(doc[1,1], from="latin1", to="UTF-8")
doc <- xmlInternalTreeParse(doc, encoding="UTF-8")

但是,解析不适用于特定的数据库行,尽管当我将此字段的内容复制到单独的文件中并从文件中解析时它起作用了。经过两天的“反复试验”,我确定了主要问题。似乎以这种方式查询短 XML 文件不会导致任何问题,但是当我查询较大的文件时,字符串在 65534 个字符后被截断。因此,缺少XML文件的结尾,无法解析文件。

我认为这可能是对我计算机上 ODBC 连接的总体限制。但是,另一个也使用 ODBC 从同一数据库中获取同一 XML 字段的程序可以毫无问题地执行此操作。所以我猜这是R 特有的问题。

有什么解决办法吗?

【问题讨论】:

  • 我没有例子可以测试!但是您尝试使用 (cast/convert) 或 as.is 选项转换 xmlfield?
  • @agstudy 我试图在sqlQuery 中设置as.is = TRUE,但这没有帮助。转换xmlfield是什么意思?
  • 类似:select cast(xmlfield as varchar(255))..
  • @agstudy 出于某种原因,varchar 不起作用,但我将语句修改为 SELECT CAST(xmlfield as CHAR(150000)) FROM... 并且 sqlQuery 以这种方式工作。但是,问题仍然存在,字段内容在 65534 个字符后被截断。

标签: sql r odbc


【解决方案1】:

我已经写信给包作者,终于收到如下答复:

你不识字不是我的问题,也不是合理的借口。

说明书上说

'\item[字符类型] 字符类型可以分为三种方式: 固定或可变长度,按最大大小和字符
设置使用。最常用的类型\footnote{
的SQL名称 这些是 \code{CHARACTER VARYING} 和 \code{CHARACTER},但这些
对于日常使用来说太麻烦了。} 是 \code{varchar} 的简称
可变长度的字符串(直到某个最大值)和 \code{char} for
固定长度的短字符串(通常用空格右填充)。
`short' 的值因 DBMS 不同而不同,至少为 254,通常是一个
几千——通常其他类型的可用时间更长
字符串。有一个健全性检查,只允许
读取时最多 65535 个字节的字符串:这可以通过
重新编译 \pkg{RODBC}。'

本手册可以在RODBC 包的doc 目录中找到。此信息未包含在参考手册中。

与此同时,我找到了一个很好的解决方案,可以在不使用RODBC 的情况下检索我的数据,我还没有尝试重新编译这个包。但我希望这个答案对那些遇到同样问题的人有所帮助。

【讨论】:

    【解决方案2】:

    如果您想更改 RODBC 的源并重新编译,使用 github 和 devtools 包相当容易:

    1. 在这里分叉回购:https://github.com/cran/RODBC
    2. 注释掉这一行(这来自 R-3.03 版本):https://github.com/cran/RODBC/blob/R-3.0.3/src/RODBC.c#L734

              if (datalen > 65535) datalen = 65535;
      
    3. (重新)从 github 安装:

      devtools::install.github("<yourgithubname>/RODBC")
      

    现在您应该可以读取大字符串了。不过需要注意的是,由于尝试分配过多的内存,您可能会遇到错误(完整性检查之后的行是:

        thisHandle->ColData[i].pData = Calloc(nRows * (datalen + 1), char);
    

    因此,最简单的方法是在 R 的 sqlQuery 调用中设置参数 rows_at_time = 1

    HTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 2021-04-23
      • 2019-12-24
      • 1970-01-01
      相关资源
      最近更新 更多