使用R的odbc包连接Oracle遇ORA-01017错误求解决
问题:R语言odbc包连接Oracle报ORA-01017错误,但RODBC可正常连接
尝试用odbc包连接Oracle数据库时,执行以下代码出现认证错误:
host <- 'something' port <- 1523 svc <- "this" pass <- '***' user <- 'me' con <- odbc::dbConnect(DBI::dbDriver("Oracle"), UID=user, PWD=pass, dbname = svc)
ORA-01017: invalid username/password; logon denied
改用完整连接字符串后仍报相同错误:
connect.string <- paste( "(DESCRIPTION=", "(ADDRESS=(PROTOCOL=tcp)(HOST=", host, ")(PORT=", port, "))", "(CONNECT_DATA=(SERVICE_NAME=", svc, ")))", sep = "") con <- odbc::dbConnect(DBI::dbDriver("Oracle"), UID=user, PWD=pass, dbname = connect.string)
ORA-01017: invalid username/password; logon denied
当前OCI驱动信息:
DBI::dbDriver("Oracle") # Driver name: Oracle (OCI) # Driver version: 1.3-1 # Client version: 12.2.0.1.0 # Connections processed: 0 # Open connections: 0 # Interruptible: FALSE # Unicode data as utf8: TRUE # Oracle type attributes: FALSE
但使用RODBC包传入相同信息可正常连接:
connect.string2 <- paste0("Driver={Oracle in OraClient12Home1};Dbq=",svc,";Uid=",user,";Pwd=",pass,";") con <-RODBC::odbcDriverConnect(connect.string2) RODBC::sqlTables(con, tableType = "TABLE") # looks perfect
希望继续使用odbc包,请问连接失败的原因是什么?
原因分析与解决方案
核心原因:驱动类型与参数处理逻辑差异
你使用的DBI::dbDriver("Oracle")是基于Oracle OCI(Call Interface)的驱动,而RODBC调用的是系统注册的ODBC驱动(Oracle in OraClient12Home1),两者的认证流程、参数解析逻辑存在差异,导致相同的用户名密码在OCI驱动下认证失败。
针对性解决方案
- 切换为ODBC驱动而非OCI驱动
odbc包支持直接调用系统中的ODBC驱动,和RODBC的逻辑一致,这是最直接的解决方案:
con <- odbc::dbConnect(odbc::odbc(), Driver = "Oracle in OraClient12Home1", Dbq = svc, Uid = user, Pwd = pass)
- 检查用户名/密码大小写敏感性
Oracle 12c+版本中,若创建用户时使用双引号指定了大小写,OCI驱动会严格遵循大小写规则,而部分ODBC驱动会自动统一转为大写。尝试用双引号包裹用户名/密码:
con <- odbc::dbConnect(DBI::dbDriver("Oracle"), UID = paste0('"', user, '"'), PWD = paste0('"', pass, '"'), dbname = connect.string)
- 调整连接字符串的服务标识
若数据库实际使用SID而非服务名,修改连接字符串中的SERVICE_NAME为SID:
connect.string <- paste( "(DESCRIPTION=", "(ADDRESS=(PROTOCOL=tcp)(HOST=", host, ")(PORT=", port, "))", "(CONNECT_DATA=(SID=", svc, ")))", sep = "")
- 配置OCI驱动依赖的环境变量
OCI驱动依赖ORACLE_HOME、TNS_ADMIN等环境变量,确保指向正确的Oracle客户端路径:
Sys.setenv(ORACLE_HOME = "C:/Oracle/OraClient12Home1") Sys.setenv(TNS_ADMIN = "C:/Oracle/OraClient12Home1/network/admin") # 之后再尝试连接 con <- odbc::dbConnect(DBI::dbDriver("Oracle"), UID=user, PWD=pass, dbname = connect.string)
内容的提问来源于stack exchange,提问作者Wave
相关产品推荐
相关产品推荐

