当我尝试将R与Access数据库连接时,我收到错误
odbcConnectAccess is only usable with 32-bit Windows
有没有人知道如何解决这个问题?
library(RODBC)
mdbConnect<-odbcConnectAccess("D:/SampleDB1/sampleDB1.mdb")
答案 0 :(得分:23)
请改用odbcDriverConnect
。如果安装了64位R,则可能必须使用32位R版本。
odbcDriverConnect("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:/SampleDB1/sampleDB1.mdb")
答案 1 :(得分:12)
这是一个单一的功能,可以将数据从32位访问传输到64位R而无需保存任何文件。该函数构建一个传递给第二个32位会话的表达式字符串;然后使用套接字服务器包(svSocket)将数据返回到原始会话。需要注意的一点是套接字服务器将访问数据保存在全局环境中,因此第二个参数用于定义输出,而不是使用“&lt; - ”来保存输出。
access_query_32 <- function(db_table = "qryData_RM", table_out = "data_access") {
library(svSocket)
# variables to make values uniform
sock_port <- 8642L
sock_con <- "sv_con"
ODBC_con <- "a32_con"
db_path <- "~/path/to/access.accdb"
if (file.exists(db_path)) {
# build ODBC string
ODBC_str <- local({
s <- list()
s$path <- paste0("DBQ=", gsub("(/|\\\\)+", "/", path.expand(db_path)))
s$driver <- "Driver={Microsoft Access Driver (*.mdb, *.accdb)}"
s$threads <- "Threads=4"
s$buffer <- "MaxBufferSize=4096"
s$timeout <- "PageTimeout=5"
paste(s, collapse=";")
})
# start socket server to transfer data to 32 bit session
startSocketServer(port=sock_port, server.name="access_query_32", local=TRUE)
# build expression to pass to 32 bit R session
expr <- "library(svSocket)"
expr <- c(expr, "library(RODBC)")
expr <- c(expr, sprintf("%s <- odbcDriverConnect('%s')", ODBC_con, ODBC_str))
expr <- c(expr, sprintf("if('%1$s' %%in%% sqlTables(%2$s)$TABLE_NAME) {%1$s <- sqlFetch(%2$s, '%1$s')} else {%1$s <- 'table %1$s not found'}", db_table, ODBC_con))
expr <- c(expr, sprintf("%s <- socketConnection(port=%i)", sock_con, sock_port))
expr <- c(expr, sprintf("evalServer(%s, %s, %s)", sock_con, table_out, db_table))
expr <- c(expr, "odbcCloseAll()")
expr <- c(expr, sprintf("close(%s)", sock_con))
expr <- paste(expr, collapse=";")
# launch 32 bit R session and run expressions
prog <- file.path(R.home(), "bin", "i386", "Rscript.exe")
system2(prog, args=c("-e", shQuote(expr)), stdout=NULL, wait=TRUE, invisible=TRUE)
# stop socket server
stopSocketServer(port=sock_port)
# display table fields
message("retrieved: ", table_out, " - ", paste(colnames(get(table_out)), collapse=", "))
} else {
warning("database not found: ", db_path)
}
}
此函数偶尔会返回错误,但它不会影响数据检索,并且似乎是因关闭套接字服务器连接而产生的。
可能还有改进的余地,但这提供了一种简单快捷的方法,可以将数据从32位访问中提取到R中。
答案 2 :(得分:7)
对于给定的答案没有成功,但这是一步一步的方法,最终为我做了诀窍。在64位上安装Windows 8。安装了64位和32位R。我的访问权限是32位。
现在我可以运行我喜欢的代码
channel <- odbcConnect("ProjectnameAcc")
Table1Dat <- sqlFetch(channel, "Table1")
答案 3 :(得分:2)
使用其他人的建议,这里有一个将32位Access数据转换为64位R的明确示例,您可以将其写入脚本,这样您就不需要手动执行这些步骤。您需要在计算机上使用32位R才能运行此脚本,并且此脚本假定32位R的默认位置,因此请根据需要进行调整。
第一个代码部分进入主脚本,第二个代码部分是您创建并从主脚本调用的小R脚本文件的全部内容,此组合提取并保存,然后从中加载数据访问数据库而不必停止。
这是我的主脚本中的位,这是从64位R中运行
## Lots of script above here
## set the 32-bit script location
pathIn32BitRScript <- "C:/R_Code/GetAccessDbTables.R"
## run the 32 bit script
system(paste0(Sys.getenv("R_HOME"), "/bin/i386/Rscript.exe ",pathIn32BitRScript))
## Set the path for loading the rda files created from the little script
pathOutUpAccdb <- "C/R_Work/"
## load the tables just created from that script
load(paste0(pathOutUpAccdb,"pots.rda"))
load(paste0(pathOutUpAccdb,"pans.rda"))
## Lots of script below here
这里是一个名为GetAccessTables.R的单独脚本
library(RODBC).
## set the database path
inCopyDbPath <- "C:/Projects/MyDatabase.accdb"
## connect to the database
conAccdb <- odbcConnectAccess2007(inCopyDbPath)
## Fetch the tables from the database. Modify the as-is and string settings as desired
pots <- sqlFetch (conAccdb,"tbl_Pots",as.is=FALSE, stringsAsFactors = FALSE)
pans <- sqlFetch(conAccdb,"tbl_Pans",as.is=FALSE, stringsAsFactors = FALSE)
## Save the tables
save(pots, file = "C/R_Work/pots.rda")
save(pans, file = "C:/R_Work/pans.rda")
close(conAccdb)
答案 4 :(得分:2)
遇到类似问题时,我碰到了这种情况,因此,我们现在可以使用非常灵活的odbc库至少有一个选择。
这里有个重要的注意事项:MS Access ODBC驱动程序不是默认MS Office安装的一部分,因此您必须从Microsoft下载合适的驱动程序(在我的情况下为Microsoft Access Database Engine 2016 Redistributable),并确保下载适当的位数(例如AccessDatabaseEngine_X64.exe)。下载完成后,它应该会自动显示在Windows ODBC数据源(64位)实用程序中,或者您可以使用odbcListDrivers函数在R会话中进行确认。
library(odbc)
# run if you want to see what drivers odbc has available
# odbcListDrivers()
# full file path to Access DB
file_path <- "~/some_access_file.accdb"
# pass MS Access file path to connection string
accdb_con <- dbConnect(drv = odbc(), .connection_string = paste0("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=",file_path,";"))
答案 5 :(得分:1)
上面的manotheshark的函数非常有用,但是我想使用SQL查询而不是表名来访问数据库,并且还要将数据库名称作为参数传递,因为我通常使用多个Access数据库。这是一个修改版本:
access_sql_32 <- function(db_sql = NULL, table_out = NULL, db_path = NULL) {
library(svSocket)
# variables to make values uniform
sock_port <- 8642L
sock_con <- "sv_con"
ODBC_con <- "a32_con"
if (file.exists(db_path)) {
# build ODBC string
ODBC_str <- local({
s <- list()
s$path <- paste0("DBQ=", gsub("(/|\\\\)+", "/", path.expand(db_path)))
s$driver <- "Driver={Microsoft Access Driver (*.mdb, *.accdb)}"
s$threads <- "Threads=4"
s$buffer <- "MaxBufferSize=4096"
s$timeout <- "PageTimeout=5"
paste(s, collapse=";")
})
# start socket server to transfer data to 32 bit session
startSocketServer(port=sock_port, server.name="access_query_32", local=TRUE)
# build expression to pass to 32 bit R session
expr <- "library(svSocket)"
expr <- c(expr, "library(RODBC)")
expr <- c(expr, sprintf("%s <- odbcDriverConnect('%s')", ODBC_con, ODBC_str))
expr <- c(expr, sprintf("%1$s <- sqlQuery(%3$s, \"%2$s\")", table_out, db_sql, ODBC_con))
expr <- c(expr, sprintf("%s <- socketConnection(port=%i)", sock_con, sock_port))
expr <- c(expr, sprintf("evalServer(%s, %s, %s)", sock_con, table_out, table_out))
expr <- c(expr, "odbcCloseAll()")
expr <- c(expr, sprintf("close(%s)", sock_con))
expr <- paste(expr, collapse=";")
# launch 32 bit R session and run the expression we built
prog <- file.path(R.home(), "bin", "i386", "Rscript.exe")
system2(prog, args=c("-e", shQuote(expr)), stdout=NULL, wait=TRUE, invisible=TRUE)
# stop socket server
stopSocketServer(port=sock_port)
# display table fields
message("Retrieved: ", table_out, " - ", paste(colnames(get(table_out)), collapse=", "))
} else {
warning("database not found: ", db_path)
}
}
我在解决如何调用manotheshark的函数方面也遇到了一些困难,并且需要深入研究svSocket包文档才能意识到调用脚本需要实例化将返回数据的对象,然后再在table_out参数中传递其NAME(不是对象本身)。以下是调用我修改版本的R脚本的示例:
source("scripts/access_sql_32.R")
spnames <- data.frame()
# NB. use single quotes for any embedded strings in the SQL
sql <- "SELECT name as species FROM checklist
WHERE rank = 'species' ORDER BY name"
access_sql_32(sql, "spnames", "X:/path/path/mydata.accdb")
这有效,但有局限性。
首先,避免任何Microsoft Access SQL扩展。例如,如果使用“访问查询”构建器,它通常会插入字段名称,如[TABLE_NAME]![FIELD_NAME]
。这些都行不通。 Access也允许非标准字段名称以&#34; 10kmSq&#34;等数字开头。并允许您在SQL SELECT [10kmSq] FROM ...
中使用它们。这也不会奏效。如果SQL语法中存在错误,则返回变量将包含错误消息。
其次,您可以返回的数据量似乎限制为64Kb。如果您尝试运行返回太多的SQL,则32位会话不会终止并且脚本会挂起。
答案 6 :(得分:1)
以下解决方案对我有用:在reading-data-from-32-bit-access-db-using-64-bit-R上找到 它说要从microsoft`
安装64位数据库引擎。然后:查找并运行“ ODBC数据源(64位)”。
然后在R中
library(RODBC)
dcon <- dbConnect(odbc::odbc(), "name-you-gave-to-your-datasource-in-3")
答案 7 :(得分:0)
我正在运行Windows 10 x64,Office 365 x64(不确定是否相关)和R 64位。我不需要切换到32位R。
就我而言,我通过安装64位版本的Microsoft Access Database Engine 2016 Redistributable使其正常工作,然后提供了自己的帐户,即rsession.exe以完全控制权限运行在HKEY_LOCAL_MACHINE\SOFTWARE\ODBC
注册表项上。
对注册表项的权限没有任何意义。我的帐户已经是此PC的管理员组的成员,并且该组已经对该键具有完全控制权限。
我使用的命令:
library("odbc")
accdb_con <- dbConnect(drv = odbc(), .connection_string = paste0("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:/full_path_to_file/buildings.mdb;"))