【发布时间】:2021-05-06 16:01:50
【问题描述】:
问题:
我有一个小型数据库,MS Access 运行良好。使用RODBC 包,我使用sqlSave 创建一个带有data.frame 的新表。我尝试使用sqlSave 和append=TRUE 将记录直接添加到表中,但是得到一个我无法附加到该表的一般错误,我不知道为什么会这样。因此,我在 R 中构建了一个 INSERT sql-string,然后使用 sqlQuery 将中间表中的值插入到最终表中。之后,从数据库中删除中间表。我有几个函数可以以这种方式对其他表执行此任务,并且它们都可以正常工作,只有这个不想表现。
我知道 sql-string 有效,因为我可以在 Access 中直接使用这两个表运行确切的 sql 语句,并且没有问题。但是,当我在我编写的函数的上下文中运行查询时,我收到错误07002 17 [Microsoft][ODBC Microsoft Access Driver]COUNT field incorrect。根据来自 MS 开发者论坛的 this SO post 和 this thread,我希望确保我正在转义任何列名,并且我已经正确引用了这些列,并且数据类型从我的 data.frame 匹配到数据库表。但是,还是不行。
代码:
# the devDB argument is the file path to the database on my machine,
# and is defined in my session environment
insertFunction <- function(df, devDB){
sqlStat <- "INSERT INTO tbl_Source ( ID, [Set], Source, [Source Desc], Type, [Age (d)], [On Product?], Formulation, [AB Program], [Date Rec] )
SELECT intermediaryTable.ID, intermediaryTable.[Set], intermediaryTable.Source,
intermediaryTable.SourceDesc, intermediaryTable.Type, intermediaryTable.Aged,
intermediaryTable.OnProduct, intermediaryTable.Formulation, intermediaryTable.ABProgram, intermediaryTable.DateRec
FROM intermediaryTable;"
res <- tryCatch(
{
# establish the connection to whichever DB
chan <- RODBC::odbcDriverConnect(connection = paste("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=", devDB, sep = ""), case = "nochange")
# if the intermediary table remains from the last update, remove it from the DB
if(any(grepl("intermediaryTable", RODBC::sqlTables(channel = chan)$TABLE_NAME))){
RODBC::sqlQuery(chan, query = "DROP TABLE intermediaryTable;")
}
# save the data.frame as a table in the database
RODBC::sqlSave(channel = chan, dat = df, tablename = "intermediaryTable", rownames = FALSE)
# run the sqlStat char string from above to add the records, and save the
# output to log the update status in a log file
dbUpdateStatus <- RODBC::sqlQuery(channel = chan, query = sqlStat)
},
error = function(cond){
return(paste("Error occurred! ", cond, " timestamp:",Sys.time()))
}
)
RODBC::sqlQuery(channel = chan, query = "DROP TABLE intermediaryTable;")
RODBC::odbcClose(channel = chan)
rm(chan)
return(res)
}
会话信息:
R version 3.6.1 (2019-07-05)
Platform: i386-w64-mingw32/i386 (32-bit)
Running under: Windows 10 x64 (build 18363)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] magrittr_2.0.1
loaded via a namespace (and not attached):
[1] Rcpp_1.0.6 fansi_0.4.2 assertthat_0.2.1 utf8_1.1.4 crayon_1.4.1 dplyr_1.0.4
[7] R6_2.5.0 odbc_1.3.0 DBI_1.1.1 lifecycle_1.0.0 pillar_1.5.0 rlang_0.4.10
[13] blob_1.2.1 vctrs_0.3.6 generics_0.1.0 ellipsis_0.3.1 RODBC_1.3-16 tools_3.6.1
[19] bit64_4.0.5 glue_1.4.2 bit_4.0.4 purrr_0.3.4 hms_1.0.0 compiler_3.6.1
[25] pkgconfig_2.0.3 tidyselect_1.1.0 tibble_3.1.0
使用的 ODBC 驱动程序是 Access Database Engine 2010,available here。
代表
表结构
表名:tbl_Source
- ID:自动编号(长整数)
- 设置:双
- 来源:双
- 来源描述:短文本
- 类型:短文本
- 年龄(d):双倍
- 关于产品?:短文本
- 公式:短文本
- AB 程序:短文本
- 日期记录:日期/时间
样本数据:
df <- data.frame(
ID = c(12495:12497),
Set = rep(998, 3),
Source = c(1:3),
SourceDesc = c("Desc 1", "Desc 2", "Desc 3"),
Type = c("Type1", "Type2", "Type3"),
Aged = c(28, 24, 5),
OnProduct = c("No", "No", "Yes"),
Formulation = rep(NA, 3),
ABProgram = rep(NA, 3),
DateRec = rep("04/01/2021", 3)
)
示例数据df 共享与顶部的insertFunction 代码一起使用的列名。
请让我知道是否有其他人认为缺少其他任何内容作为代表。
谢谢!
【问题讨论】: