如何在 64 位窗口中将 R 与 Access 数据库连接?
Posted
技术标签:
【中文标题】如何在 64 位窗口中将 R 与 Access 数据库连接?【英文标题】:How to connect R with Access database in 64-bit Window? 【发布时间】:2012-10-25 14:21:35 【问题描述】:当我尝试将 R 与 Access 数据库连接时,出现错误
odbcConnectAccess is only usable with 32-bit Windows
有人知道如何解决这个问题吗?
library(RODBC)
mdbConnect<-odbcConnectAccess("D:/SampleDB1/sampleDB1.mdb")
【问题讨论】:
也许this 的回答也可能有帮助,我不确定。 谢谢乔兰。我会尝试这两种选择。 它适用于 32 位。谢谢。 此错误不是由 Windows 安装引起的,但如果您安装了 32 位 Office 并尝试使用 64 位 R。我在下面添加了一个脚本,它将启动第二个 32-位 R 会话从 32 位 Access 读取数据,然后将数据复制回原始 64 位 R 会话。 【参考方案1】:请改用odbcDriverConnect
。如果您安装了 64 位 R,则可能必须使用 32 位 R 版本。
odbcDriverConnect("Driver=Microsoft Access Driver (*.mdb, *.accdb);DBQ=D:/SampleDB1/sampleDB1.mdb")
【讨论】:
谢谢您。我刚试了一下,报了一行错误:( 是的,我使用的是 64 位 R。如果有帮助,我会将其更改为 32 位。 是的,我现在将其更改为 32 位 R 并且它正在工作。感谢您的提示。 我正在尝试这个,但我仍然面临同样的问题。它连接到亚马逊的数据库但无法访问 安装 AccessDatabaseEngine_x64.exe 对我有用【参考方案2】:这里有一个函数可以将数据从 32 位访问传输到 64 位 R,而无需保存任何文件。该函数构建一个表达式字符串,该字符串传递给第二个 32 位会话;然后使用套接字服务器包(svSocket)将数据返回到原始会话。需要注意的一点是socket服务器将访问数据保存在全局环境中,所以第二个参数用于定义输出,而不是使用“
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 中。
【讨论】:
使用prog <- file.path(R.home(), "bin", "i386", "Rscript.exe")
避免依赖R_HOME
会稍微安全一些。【参考方案3】:
给出的答案没有成功,但这里是一步一步的方法,最终对我有用。在 64 位上安装 Windows 8。安装了 64 位和 32 位 R。我的 Access 是 32 位的。
使用步骤,假设是 windows 8 上的 32 位 Access
-
选择 32 位 R(只是 R studio 中的一个设置)
在 Windows 上搜索设置 ODBC 数据源(32 位)
转到系统 DSN>添加
选择驱动程序执行 Microsoft Access (*.mdb) > 完成
数据源名称:ProjecnameAcc
描述:项目名称Acc
确保实际选择数据库 > 确定
现在我可以运行我喜欢的代码了
channel <- odbcConnect("ProjectnameAcc")
Table1Dat <- sqlFetch(channel, "Table1")
【讨论】:
【参考方案4】:我在遇到类似问题时遇到了这个 SO,此时我们至少还有一个使用极其灵活的 odbc 库的选项。
这里有一个重要说明:MS Access ODBC 驱动程序不是默认 MS Office 安装的一部分,因此您必须从 Microsoft 下载适当的驱动程序(在我的情况下为 Microsoft Access Database Engine 2016 Redistributable)并确保下载适当的位数(例如 AccessDatabaseEngine_X64.exe)。下载后,它应该会自动显示在您的 Windows ODBC 数据源(64 位)实用程序中,或者您可以在 R 会话中使用 odbcListDrivers 函数进行确认。
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,";"))
【讨论】:
这在 Windows 10 上对我有用。如果它不起作用,请运行odbcListDrivers()
。如果“Microsoft Access Driver (*.mdb, *.accdb)”没有出现,您将需要安装上面讨论的 Access 可再发行组件。当我尝试安装 AccessDatabaseEngine_X64.exe 时,我收到有关“Office 16 Click-to-Run Extensibility Component”冲突的错误。我能够按照错误消息上的说明解决此冲突。安装后,当我在 R 中运行 odbcListDrivers()
时,就会出现驱动程序。【参考方案5】:
根据其他人的建议,这是一个将 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)
【讨论】:
【参考方案6】:上面 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 包文档才意识到调用脚本需要实例化返回数据的对象,然后传递它的 NAME (不是对象本身)在 table_out 参数中。这是一个调用我修改后的版本的 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 还允许以“10kmSq”之类的数字开头的非标准字段名称,并允许您在 SQL 中使用它们,例如SELECT [10kmSq] FROM ...
。这也行不通。如果 SQL 语法有错误,返回变量将包含错误消息。
其次,您可以返回的数据量似乎限制为 64Kb。如果您尝试运行返回过多的 SQL,则 32 位会话不会终止并且脚本会挂起。
【讨论】:
非常感谢,成功了!【参考方案7】:以下解决方案对我有用:发现于 reading-data-from-32-bit-access-db-using-64-bit-R 它说要从以下位置安装 64 位数据库引擎:microsoft`
然后:找到并运行“ODBC 数据源(64 位)”。
-
在“user-DSN”选项卡中单击“添加”
选择:“Microsoft Access Driver”并保存
为您的新数据源命名(稍后连接数据库时将使用此名称)
点击“选择”:选择您的access数据库所在目录并保存
然后在 R 中:
library(RODBC)
dcon <- dbConnect(odbc::odbc(), "name-you-gave-to-your-datasource-in-3")
【讨论】:
【参考方案8】:我正在运行 Windows 10 x64、Office 365 x64(不确定是否相关)和 R 64 位。我不需要切换到 32 位 R。
在我的例子中,我通过安装 64 位版本的 Microsoft Access Database Engine 2016 Redistributable 然后给我自己的帐户(rsession.exe 运行为)提供对HKEY_LOCAL_MACHINE\SOFTWARE\ODBC
注册表项。
注册表项的权限没有意义。我的帐户已经是这台电脑的 Administrators 组的成员,并且该组已经对该密钥具有完全控制权限。
我使用的命令:
library("odbc")
accdb_con <- dbConnect(drv = odbc(), .connection_string = paste0("Driver=Microsoft Access Driver (*.mdb, *.accdb);DBQ=C:/full_path_to_file/buildings.mdb;"))
【讨论】:
以上是关于如何在 64 位窗口中将 R 与 Access 数据库连接?的主要内容,如果未能解决你的问题,请参考以下文章
使用 c# 在 32 位和 64 位窗口中打开 ms-access .mdb