RODBC:积极转换字符和数字(有/无原样)
Posted
技术标签:
【中文标题】RODBC:积极转换字符和数字(有/无原样)【英文标题】:RODBC: chars and numerics converted aggressively (with/without as.is) 【发布时间】:2016-07-18 17:58:51 【问题描述】:与 https://***.com/a/33284035/3358272 相关,我发现从 SQL Server (2014) 中提取数据的行为不一致。
library(RODBC)
sqlQuery(.conn, "CREATE TABLE r2test ( [mychar] [NVARCHAR](16), [mynum] [FLOAT])")
# character(0)
sqlQuery(.conn, "INSERT INTO r2test (mychar,mynum) VALUES ('1',3.141593),('2',6.283185)")
character(0)
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE))
# 'data.frame': 2 obs. of 2 variables:
# $ mychar: int 1 2
# $ mynum : num 3.14 6.28
在该示例中,我们看到了不希望的行为:mychar
的字符在内部被转换为整数。根据前面提到的 SO 答案,as.is
选项可以解决这个问题,但也有一个不幸的副作用,即强制将十进制表示的浮点数转换为字符串:
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE, as.is = TRUE))
# 'data.frame': 2 obs. of 2 variables:
# $ mychar: chr "1" "2"
# $ mynum : chr "3.1415929999999999" "6.2831849999999996"
如果mychar
中的至少一个实际上不可整数化,则一切正常:
sqlQuery(.conn, "INSERT INTO r2test (mychar,mynum) VALUES ('a',9.424778)")
# character(0)
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE))
# 'data.frame': 3 obs. of 2 variables:
# $ mychar: chr "1" "2" "a"
# $ mynum : num 3.14 6.28 9.42
不幸的是,数据模型不支持任意添加一些东西来鼓励这种行为(或者我只是没有想到一个足够好的方法来做到这一点)。该数据模型使得mychar
的值包括01
和1
,它们在字符方面是不同的。我发现的唯一解决方法是使用 as.is = TRUE
,这将要求我 as.numeric
所有相关列,这既乏味又(理论上)不必要的工作。
由于文档建议需要设置DBMSencoding
,我检查了当前编码(由https://***.com/a/5182469/3358272 帮助):
sqlQuery(.conn, "SELECT SERVERPROPERTY('Collation')")
# 1 SQL_Latin1_General_CP1_CI_AS
我尝试使用(用于踢球):DBMSencoding="latin1"
、DBMSencoding="UTF-8"
,并明确使用默认的DBMSencoding=""
,但行为没有任何变化。
如何鼓励不要过度强制数据类型的行为?
目前在 ubuntu 上使用 R-3.2.5 和 RODBC-1.3.13。
【问题讨论】:
【参考方案1】:如果我理解正确,我认为这就是你要找的,
str(sqlQuery(
.conn,
"SELECT * FROM r2test",
stringsAsFactors = FALSE,
as.is = c(TRUE, FALSE)
))
#'data.frame': 2 obs. of 2 variables:
# $ mychar: chr "1" "2"
# $ mynum : num 3.14 6.28
其中as.is
被指定为逻辑向量(必须与结果集中的列数具有相同的长度)。公平地说,这并没有很好地说明。 sqlQuery
的手册页只是将您引向 read.table
中的 as.is
参数,其中指出:
注意 as.is 是按列指定的(而不是按变量),所以 包括行名列(如果有)和任何列 跳过。
这种方法的缺点是您需要提前知道要转换哪些列以及不转换哪些列。我个人不明白 为什么 默认行为不仅仅是将 SQL 字符类型映射到 R 字符类型、将 SQL 数字类型映射到 R 数字类型等,但也许有一个很好的理由在后端。自动将'1'
, '2'
, ... 转换为整数 不是 对我来说似乎是一个很大的“功能”。
【讨论】:
我没有考虑过使用逻辑 vector,它确实稍微改善了一些情况,提供了更直接的出路,谢谢!同意“不明白为什么”,但话又说回来,我(还没有)提供编写代码(并提交 PR)来以不同的方式处理事情。 是的,当函数参数的默认值为TRUE
或 FALSE
但也接受逻辑 向量 时,这有点令人困惑。同上,我对这个软件包有一个长期的看法,即 sqlUpdate
没有像宣传的那样工作,但我还没有开始着手开发补丁,所以我不能大声抱怨......跨度>
nrussell,除了 R-sigs-db,您知道任何其他 RODBC 特定的讨论论坛吗?问题和 PR 的源代码?我想讨论参数化查询、部分表 sqlSave
以及其他不必要地限制我使用 RODBC 的事情。
我不知道有什么不幸的——我看到的这个包的唯一存储库是在 CRAN 的只读 GitHub 镜像上,但这只是 CRAN 自动导出的东西,而不是发展通道。但是,您可以考虑通过说明文件中列出的电子邮件联系 Brian Ripley。开发可能通过 SVN 或其他方式进行,但无论如何,作为当前的维护者,我想他将是谈论此事的最佳人选。我也对这些功能感兴趣,因为我在工作中花费大量时间使用 SQL (Server)。以上是关于RODBC:积极转换字符和数字(有/无原样)的主要内容,如果未能解决你的问题,请参考以下文章
c语言,编程实现,把输入的一行字符原样输出,若是大写字母则转换成小写字母