当结果集很大时,RODBC会丢失日期时间的时间值

时间:2014-04-06 20:21:27

标签: sql r rodbc

所以这非常很奇怪。如果结果集足够大,RODBC似乎会删除DateTime SQL列的时间部分。 (查询是针对SQL Server 2012计算机运行的,是的,当我在SQL Server端运行它们时,无论返回多少行,它们都会生成相同且正确的结果。)

例如,以下内容完美无缺:

myconn <- odbcConnect(dsnName, uid, pwd)
results <- sqlQuery(myconn, "SELECT TOP 100 MyID, MyDateTimeColumn from MyTable ORDER BY MyDateTimeColumn DESC")
close(myconn)

在R中,以下工作符合预期:

> results$MyDateTimeColumn[3]
[1] "2013-07-01 00:01:22 PDT"

这是一个有效的POSIXct日期时间。但是,当返回10,000到100,000行之间时,突然间时间部分消失:

myconn <- odbcConnect(dsnName, uid, pwd)
bigResults <- sqlQuery(myconn, "SELECT TOP 100000 MyID, MyDateTimeColumn from MyTable ORDER BY MyDateTimeColumn DESC")
close(myconn)

(相同的代码,只返回了更多的行; 注意完全相同的行现在已经丢失了时间组件),R回复:

> bigResults$MyDateTimeColumn[3]
[1] "2013-07-01 PDT"

请注意,现在缺少时间(这不是一个不同的行;它与之前的完全相同的行),如下所示:

>strptime(results$TriggerTime[3], "%Y-%m-%d %H:%M:%S")
[1] "2013-07-01 00:01:22"

>strptime(bigResults$TriggerTime[3], "%Y-%m-%d %H:%M:%S")
[1] NA

显然,解决方法是增量查询 - 附加或导出到CSV和导入到R,但这看起来很奇怪。有没有见过这样的人?

配置:我使用的是最新版本的RODBC(1.3-10),可以复制在Windows x64上运行的R安装和在Mac OS X 10.9上运行的R安装上的行为(Mavericks )。

编辑#2 根据请求添加dput()的输出以比较对象:

> dput(results[1:10,]$MyDateTimeColumn)
structure(c(1396909903.347, 1396909894.587, 1396909430.903, 1396907996.9, 1396907590.02, 1396906077.887, 1396906071.99, 1396905537.36, 1396905531.413, 1396905231.787), class = c("POSIXct", "POSIXt"), tzone = "")

> dput(bigResults[1:10,]$MyDateTimeColumn)
structure(c(1396854000, 1396854000, 1396854000, 1396854000, 1396854000, 1396854000, 1396854000, 1396854000, 1396854000, 1396854000), class = c("POSIXct", "POSIXt"), tzone = "")

看起来基础数据实际上是由于查询返回的行数而发生变化,这是完全奇怪的。

8 个答案:

答案 0 :(得分:6)

sqlQuery()有一个名为as.is的选项。将其设置为TRUE将拉出所有内容,例如Microsoft SQL Management Studio。

答案 1 :(得分:2)

我也应对同样的问题。更奇怪的是,在大型数据集上,一列会导入日期和时间,而另一列只导入日期。

我的建议是在SQL中分割数据/时间

 myconn <- odbcConnect(dsnName, uid, pwd)
 results <- sqlQuery(myconn, "SELECT TOP 100 MyID, format(MyDateTimeColumn,"HH:mm:ss") as MyTimeColumn,format(MyDateTimeColumn,"yyyy-MM-dd") as MyDateColumn  from MyTable ORDER BY MyDateTimeColumn DESC")
 close(myconn)

然后将它们组合在R中。希望能帮助到你。

答案 2 :(得分:1)

这可能是夏令时问题。如果您的时区中存在时间(因为夏令时),可能会导致类似这样的事情。

答案 3 :(得分:1)

我遇到了同样的问题并得出结论,这是由于DST:

这失败了: as.POSIXct(c("2015-03-29 01:59:22", "2015-03-29 02:00:04"))

这有效: as.POSIXct(c("2015-03-29 01:59:22", "2015-03-29 02:00:04"), tz="UTC")

我找不到如何强迫tz =&#34; UTC&#34;在默认的RODBC行为中,无论如何使用as.is = TRUE并自行转换列都可以完成工作。

注意:起初我的印象是它是由于巨大的结果,但实际上是因为在巨大的结果中我有更多的机会跨越DST更新。

答案 4 :(得分:1)

这是一个较旧的问题,但在尝试以编程方式从15个不同的.accdb读取数据时,我遇到了类似的问题。除了3月份的数据库之外,每个数据库都正确读取了所有POSIXct个字段,我从中推断出 某种夏令时问题。

我的解决方案(因为我不想对dB进行多次查询,然后rbind()所有内容一起)是改变我的功能以包含行

#Get initial tz
current_tz <- Sys.timezone()
Sys.setenv(TZ = "America/Phoenix")

[BODY OF FUNCTION]

Sys.setenv(TZ = curent_tz)

包含这几行之后,正在正确读取March数据库中的日期/时间字段。

答案 5 :(得分:1)

sqlQuery(ch, getSQL(sqlquerypath)) 

从日期时间列中删除了时间。

sqlQuery(ch, getSQL(sqlquerypath), as.is = TRUE) 

解决了这个问题。

答案 6 :(得分:0)

我认为这是从日期范围包括转换到夏令时的日期被剥夺的时间。如果您选择的时段不包括夏令时班次,则会保留时间(例如,从2007年1月1日到2007年3月1日。可以通过更改计算机上的系统时间来避免这种情况一个时区(例如,亚利桑那州),没有夏令时转移(听起来奇怪,但它对我有用)。

要解决此问题,请将DateTimes作为字符导入(使用“as.is”),然后将它们转换为POSIXct。您也可以使用“strptime”转换为POSIXlt并允许您指定格式。下面是一个SQL查询的示例,其中DateTimes被导入为.is(TRUE),但是相关的DataValues不是(FALSE),然后DateTime被转换为R日期格式:

data <- sqlQuery(channel, paste("SELECT LocalDateTime, DataValue FROM DataValues WHERE  LocalDateTime >= '1/1/2007 0:00' AND LocalDateTime < '1/1/2008 0:00' ORDER BY LocalDateTime ASC"),as.is=c(TRUE,FALSE))

data$LocalDateTime <- as.POSIXct(totalP$LocalDateTime,tz="MST")

答案 7 :(得分:0)

为什么在从sqlQuery()返回的大型数据集上发生这种情况?我不知道。但是能够通过在sql调用中应用sql转换来解决它:

data&lt; - sqlQuery(channel,“SELECT CONVERT(nvarchar(24),DtTimeField,21)AS HourDt,* FROM ...

这是你的解决方法。