Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在64位窗口中连接R和Access数据库?_R_Ms Access_Rodbc - Fatal编程技术网

如何在64位窗口中连接R和Access数据库?

如何在64位窗口中连接R和Access数据库?,r,ms-access,rodbc,R,Ms Access,Rodbc,当我尝试将R与Access数据库连接时,我遇到一个错误 odbcConnectAccess is only usable with 32-bit Windows 有人知道如何解决这个问题吗 library(RODBC) mdbConnect<-odbcConnectAccess("D:/SampleDB1/sampleDB1.mdb") 改用odbcDriverConnect。如果安装了64位R,则可能必须使用32位R版本 odbcDriverConnect("Driver={Mic

当我尝试将R与Access数据库连接时,我遇到一个错误

odbcConnectAccess is only usable with 32-bit Windows
有人知道如何解决这个问题吗

library(RODBC) 
mdbConnect<-odbcConnectAccess("D:/SampleDB1/sampleDB1.mdb")
改用odbcDriverConnect。如果安装了64位R,则可能必须使用32位R版本

odbcDriverConnect("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:/SampleDB1/sampleDB1.mdb")

在给出答案时没有成功,但下面是一步一步的方法,它最终为我成功了。在64位上安装Windows 8。安装了64位和32位R。我的访问权限是32位

使用步骤,假定在windows 8上具有32位访问权限 选择32位R只是R studio中的一个设置 在windows上搜索设置32位ODBC数据源 转到系统DSN>添加 选择驱动程序执行Microsoft Access*.mdb>Finish 数据源名称:ProjecnameAcc 描述:ProjectnameAcc 确保实际选择数据库>确定 现在我可以运行我喜欢的代码了

channel <- odbcConnect("ProjectnameAcc")
Table1Dat <- sqlFetch(channel, "Table1")

使用其他人的建议,这里有一个将32位访问数据写入64位R的显式示例,您可以将其写入脚本,这样就不需要手动执行这些步骤。您的计算机上确实需要有32位R才能运行此脚本,并且此脚本假定32位R的默认位置,因此根据需要进行调整

第一个代码部分进入主脚本,第二个代码部分是您创建的一个小R脚本文件的全部内容,并从主脚本调用,这种组合提取、保存并从access数据库加载数据,而无需停止

这是我的主脚本中的位,它是从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)

这里有一个函数,可以将数据从32位访问传输到64位R,而无需保存任何文件。该函数构建一个表达式字符串,该字符串被传递给第二个32位会话;然后使用套接字服务器包svSocket将数据返回到原始会话。需要注意的一点是,套接字服务器将访问数据保存在全局环境中,因此第二个参数用于定义输出,而不是使用上面ManotheSharek的函数非常有用,但我想使用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)
  }
}
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")
我还遇到了一些困难,无法确定如何调用ManotheSharek的函数,需要深入研究svSocket包文档,才能意识到调用脚本需要实例化将返回数据的对象,然后在table_out参数中传递其名称,而不是对象本身。以下是调用我的修改版本的R脚本示例:

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)
  }
}
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扩展。例如,如果使用Access查询生成器,它通常会插入字段名,如[TABLE_NAME]![字段名称]。这些都行不通。Access还允许以数字(如10kmSq)开头的非标准字段名,并允许您在SQL中使用它们,如选择[10kmSq]FROM。。。。这也行不通。如果SQL语法中有错误,返回变量将包含错误消息


其次,您可以返回的数据量似乎限制在64Kb以内。如果您试图运行返回太多的SQL,32位会话不会终止,脚本将挂起。

我遇到了类似的问题,因此在遇到类似问题时,我们至少还有一个选项可以使用极其灵活的odbc库

不过,这里需要注意的一点是:MS Access ODBC驱动程序不是默认MS Office安装的一部分,因此您必须从Microsoft Access数据库引擎2016下载相应的驱动程序。在我的情况下,该驱动程序是可再发行的,并确保下载相应的位,例如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,";"))

以下解决方案对我有效:在上找到 它表示要从以下位置安装64位数据库引擎:`

然后:查找并运行64位ODBC数据源

在选项卡用户DSN中,单击添加 选择:Microsoft Access驱动程序并保存 为新数据源指定一个名称,以后连接到数据库时将使用该名称 单击选择:选择access数据库所在的目录并保存 然后在R中:

library(RODBC)
dcon <- dbConnect(odbc::odbc(), "name-you-gave-to-your-datasource-in-3")

我正在运行Windows 10 x64、Office 365 x64(不确定是否相关)和R 64位。我不需要切换到32位R

在我的例子中,我通过安装的64位版本,然后通过对HKEY_LOCAL_MACHINE\SOFTWARE\ODBC注册表项授予我自己的帐户(rsession.exe以完全控制权限运行)使其正常工作

注册表项上的权限没有意义。我的帐户已是此电脑管理员g的成员 并且该组已经对该键具有完全控制权限

我使用的命令:

library("odbc")

accdb_con <- dbConnect(drv = odbc(), .connection_string = paste0("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:/full_path_to_file/buildings.mdb;"))

也许这个答案也会有帮助,我不确定。谢谢乔兰。我会尝试两种选择。它是32位的。谢谢。此错误不是由Windows安装引起的,但如果您安装了32位Office并尝试使用64位R,则会出现此错误。我在下面添加了一个脚本,该脚本将启动第二个32位R会话,从32位访问读取数据,然后将数据复制回原始的64位R会话。谢谢。我刚刚尝试了一下,并给出了一行错误:是的,我使用的是64位R。如果有帮助的话,我会将其更改为32位。是的,我现在将其更改为32位R,并且它正在工作。谢谢你的提示。我正在尝试,但我仍然面临同样的问题。它连接到amazon中的数据库,但不连接accessIt为我安装AccessDatabaseEngine_x64起作用。使用prog稍微安全一点。非常感谢,这很好!这对我在Windows10上的表现很有帮助。如果它不工作,请运行odbcListDrivers。如果Microsoft Access驱动程序*.mdb、*.accdb未显示,则需要安装上面讨论的Access可再发行程序。当我试图安装AccessDatabaseEngine_X64.exe时,我遇到了一个关于Office 16单击以运行扩展性组件冲突的错误。我能够按照错误消息上的说明解决此冲突。安装后,当我在R中运行odbcListDrivers时,驱动程序出现了。