R odbc 无法找到 oracle 驱动程序,即使它在那里

问题描述 投票:0回答:1

这是我从 RStudio(和 R,使用 sudo 运行)收到的错误:

> odbc::dbConnect(odbc::odbc(), driver = "/opt/oracle/instantclient_23_4/libsqora.so.23.1")
Error: nanodbc/nanodbc.cpp:1138: 00000
[unixODBC][Driver Manager]Can't open lib '/opt/oracle/instantclient_23_4/libsqora.so.23.1' : file not found 

使用 DSN 运行

isql
会导致:

[28000][unixODBC][Oracle][ODBC][Ora]ORA-01017: invalid username/password; logon denied

那么问题可能出在

R
odbc
包上?

会议信息:

R version 4.4.0 (2024-04-24)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 22.04.4 LTS

other attached packages:
[1] odbc_1.4.2 DBI_1.2.2 

libsqora
已设置权限
777
:

ls -l /opt/oracle/instantclient_23_4/libsqora.so.23.1 -rwxrwxrwx 1 rdpdp rdpdp 802848 4月25日01:38 /opt/oracle/instantclient_23_4/libsqora.so.23.1

和:

odbcinst --version
unixODBC 2.3.9

--- 编辑 ---

感谢这里的评论,我已经使用

system
来生成更多诊断信息。从终端运行 R 后,我执行
system("isql -v test asdf asdf")
,它返回

[01000][unixODBC][Driver Manager]Can't open lib '/opt/oracle/instantclient_23_4/libsqora.so.23.1' : file not found
[ISQL]ERROR: Could not SQLConnect

这是因为:

system('ldd /opt/oracle/instantclient_23_4/libsqora.so.23.1')
    linux-vdso.so.1 (0x00007fff1a9bc000)
    /opt/datadog/apm/inject/launcher.preload.so (0x0000798d847fb000)
    libdl.so.2 => /usr/lib/x86_64-linux-gnu/libdl.so.2 (0x0000798d847f6000)
    libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x0000798d8470f000)
    libpthread.so.0 => /usr/lib/x86_64-linux-gnu/libpthread.so.0 (0x0000798d8470a000)
    librt.so.1 => /usr/lib/x86_64-linux-gnu/librt.so.1 (0x0000798d84705000)
    libaio.so.1 => /usr/lib/x86_64-linux-gnu/libaio.so.1 (0x0000798d846fe000)
    libresolv.so.2 => /usr/lib/x86_64-linux-gnu/libresolv.so.2 (0x0000798d846ea000)
    libclntsh.so.23.1 => not found
    libclntshcore.so.23.1 => not found
    libodbcinst.so.2 => /usr/lib/x86_64-linux-gnu/libodbcinst.so.2 (0x0000798d846c1000)
    libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x0000798d84400000)
    /lib64/ld-linux-x86-64.so.2 (0x0000798d848be000)
    libltdl.so.7 => /usr/lib/x86_64-linux-gnu/libltdl.so.7 (0x0000798d846b4000)

即两个文件没有链接,因为:

system("echo $LD_LIBRARY_PATH")
/usr/lib/R/lib:/usr/lib/x86_64-linux-gnu:/usr/lib/jvm/default-java/lib/server

可以通过运行

Sys.setenv(LD_LIBRARY_PATH="/opt/oracle/instantclient_23_4")
来修复此问题,之后命令
system("isql -v test asdf asdf")
返回:

[28000][unixODBC][Oracle][ODBC][Ora]ORA-01017: invalid username/password; logon denied
Help: https://docs.oracle.com/error-help/db/ora-01017/

[ISQL]ERROR: Could not SQLConnect

这意味着现在它已经固定在shell

R
中运行了。不幸的是
odbc
仍然无法连接。所以我怀疑这与
odbc
认为的
LD_LIBRARY_PATH
有关。

--- 2024 年 5 月 20 日编辑 ---

有趣的是,对于

system("isql -v ...")
oracle
客户端安装文件夹需要位于路径的第一个位置。即:

Sys.setenv(LD_LIBRARY_PATH=paste0("/opt/oracle/instantclient_23_4", ':', '/lib64/', ':', Sys.getenv('LD_LIBRARY_PATH')))

有效,但是:

Sys.setenv(LD_LIBRARY_PATH=paste0(Sys.getenv('LD_LIBRARY_PATH'), ':', "/opt/oracle/instantclient_23_4", ':', '/lib64/'))

没有。

我还尝试使用以下方法重新安装

odbc

withr::with_makevars(c(PKG_LIBS="-L/opt/oracle/instantclient_23_4/ -L/lib64/"), install.packages("odbc"), assignment="+=")

没有成功。

在有问题的链接库上尝试

dyn.load
会导致不同的错误:

dyn.load("/opt/oracle/instantclient_23_4/libclntsh.so.23.1")
dyn.load("/opt/oracle/instantclient_23_4/libclntshcore.so.23.1")
dyn.load("/opt/oracle/instantclient_23_4/libnnz.so")

> DBI::dbConnect(odbc::odbc(), 'test', pwd = 'asdf')
Error: nanodbc/nanodbc.cpp:1138: 00000
[unixODBC][Driver Manager]Driver's SQLAllocHandle on SQL_HANDLE_HENV failed
r oracle odbc ubuntu-22.04
1个回答
0
投票

我花了几天的时间才将 Oracle 即时客户端安装到 Docker 容器中并与 R 连接。我不认为我的任何挣扎都是专门针对 R 的,但我不记得所有细节。我可以在这里分享 Dockerfile,以防它有用。

也许答案就在这些 Dockerfile 命令中。

另外两个想法

  1. 您是否使用 Oracle 即时客户端安装附带的

    .ini
    脚本来安装
    odbc_update_ini.sh
    文件?这个脚本有点棘手,你必须给它一些具体的参数。请参阅注释
    # writes odbc ini file
    下的命令作为示例。

  2. odbc::odbcListDrivers()
    是调试 odbc 连接时运行的有用函数。

FROM rocker/shiny-verse

# system
RUN apt-get update
RUN apt-get install -y unixodbc alien libaio1

# oracle driver installations:
# https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html#ic_x64_inst
# https://www.oracle.com/database/technologies/releasenote-odbc-ic.html

# paths
RUN sh -c  'echo /usr/lib/oracle/21/client64/lib/ > /etc/ld.so.conf.d/oracle.conf'
RUN ldconfig

# install instant client basic lite
# this is a prerequisite for the odbc driver
# to install an rpm file on Ubuntu, need alien
RUN wget https://download.oracle.com/otn_software/linux/instantclient/2110000/oracle-instantclient-basiclite-21.10.0.0.0-1.el8.x86_64.rpm
RUN alien -i oracle-instantclient-basiclite-21.10.0.0.0-1.el8.x86_64.rpm

# install instant client odbc
RUN wget https://download.oracle.com/otn_software/linux/instantclient/2110000/oracle-instantclient-odbc-21.10.0.0.0-1.el8.x86_64.rpm
RUN alien -i oracle-instantclient-odbc-21.10.0.0.0-1.el8.x86_64.rpm

RUN export PATH=/usr/lib/oracle/21/client64/bin:$PATH

# writes odbc ini file
RUN /usr/lib/oracle/21/client64/bin/odbc_update_ini.sh "/" "/usr/lib/oracle/21/client64/lib" "oracle"

# test in R
RUN R -e 'install.packages("odbc")'
CMD R -e '\
  library(odbc); \
  library(DBI); \
  con <- dbConnect(odbc(), Driver = "oracle", DBQ = "xxx&yy.com:1521/appsdv", \
    UID = "myid", PWD = "mypd", Port = 1521); \
  con |> dbListTables(schema_name = "MYSCHEMA") |> print()'

© www.soinside.com 2019 - 2024. All rights reserved.