• 达梦DBLINK之DM访问Oracle问题处理


    达梦DBLINK之DM访问Oracle配置步骤

    下面所有的问题基本上都是在使用ODBC的方式创建DBLINK时遇到,所以强烈建议DM访问Oracle的DBLINK创建时采用Oracle OCI来进行访问。

    强烈建议使用Oracle OCI的方式创建DBLINK
    强烈建议使用Oracle OCI的方式创建DBLINK
    强烈建议使用Oracle OCI的方式创建DBLINK

    问题1:DBLINK加载动态库失败

    使用DBLINK访问Oracle目的端报错"DBLINK加载库文件失败"

    SQL> select * from t1@link1;
    select * from t1@link1;
    [-2245]:Error in line: 1
    DBLINK load library fail.
    
    • 1
    • 2
    • 3
    • 4
    原因

    (1)第一种情况:DM DBLINK使用的是ODBC方式创建,一般是由于Oracle odbc驱动包缺少依赖库文件导致。

    (2)第二种情况:DM DBLINK使用的是Oracle OCI方式创建,一般是由于DM数据库未加载Oracle OCI驱动,需要重启DM数据库。(前提是LD_LIBRARY_PATH或者ldconfig配置正确)

    解决办法

    (1)第一种情况的解决办法

    首先,使用ldd命令检查Oracle odbc驱动包是否缺少依赖库文件。如下:

    [root@localhost instantclient_19_13]# ldd libsqora.so.19.1 
    	linux-vdso.so.1 =>  (0x00007ffeef3cd000)
    	libdl.so.2 => /lib64/libdl.so.2 (0x00007ffafac45000)
    	libm.so.6 => /lib64/libm.so.6 (0x00007ffafa943000)
    	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ffafa727000)
    	libnsl.so.1 => /lib64/libnsl.so.1 (0x00007ffafa50d000)
    	librt.so.1 => /lib64/librt.so.1 (0x00007ffafa305000)
    	libaio.so.1 => /lib64/libaio.so.1 (0x00007ffafa103000)
    	libresolv.so.2 => /lib64/libresolv.so.2 (0x00007ffaf9ee9000)
    	libclntsh.so.19.1 => /opt/oracle/instantclient_19_13/libclntsh.so.19.1 (0x00007ffaf5d76000)
    	libclntshcore.so.19.1 => /opt/oracle/instantclient_19_13/libclntshcore.so.19.1 (0x00007ffaf57d2000)
    	libodbcinst.so.2 => not found        ###这里缺少依赖
    	libc.so.6 => /lib64/libc.so.6 (0x00007ffaf5404000)
    	/lib64/ld-linux-x86-64.so.2 (0x00007ffafb103000)
    	libnnz19.so => /opt/oracle/instantclient_19_13/libnnz19.so (0x00007ffaf4d92000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    然后,使用find命令查找系统上对应的动态库文件,查找到之后加入到LD_LIBRARY_PATH系统环境变量,或者添加到 /etc/ld.so.conf.d目录下指定的配置文件中。如下:

    [root@localhost ~]# echo /usr/local/lib > /etc/ld.so.conf.d/libodbc.conf
    [root@localhost ~]# ldconfig
    
    • 1
    • 2

    (2)第二种情况的解决办法

    需要重启DM数据库服务,重启服务后数据库会加载Oracle OCI驱动,然后可以正常使用DBLINK访问Oracle数据库。

    问题2:查询的表为非DBLINK用户下的表

    DBLINK使用odbc方式在某些版本中存在查询目的表并非指定用户下的表,需要在查询语句中指定用户名或者模式名前缀。

    现象如下:

    image-20211025230041143

    原因:

    不加用户名或者模式名前缀,实际查询的是sys用户下的对象。

    解决办法

    方法1:数据库升级到更高版本(比如2-70版本)

    方法2:在访问的对象前面加上目的表的用户名或者模式名

    方法3(推荐):DBLINK创建不使用ODBC的方式,使用Oracle OCI进行访问。如果数据库启动时未加载Oracle OCI驱动,需要重启数据库加载Oracle OCI驱动。

    问题3:查询公共同义词等公共对象失败

    在高版本上(1-2-70版本),DBLINK使用ODBC方式查询公共同义词等,包括动态性能视图等,会直接报错。报错信息如下:

    image-20211026103954961

    在低版本中是可以正常访问,原因见问题2

    原因:

    初步判断可能是为了解决低版本下使用DBLINK访问时不加目的表的用户名或者模式名前缀无法访问DBLINK用户下的表的问题,即问题2。而在高版本中为了解决问题2,使用DBLINK访问时会自动给SQL语句访问对象添加一个DBLINK用户名前缀,所以导致在该版本中操作非DBLINK用户下的对象时报错。

    解决办法

    方法1(推荐):DBLINK创建不使用ODBC的方式,使用Oracle OCI进行访问。如果数据库启动时未加载Oracle OCI驱动,需要重启数据库加载Oracle OCI驱动。

    方法2:在Oracle数据库中对应用户下创建有权限访问的非本用户下的对象同义词

    类似操作如下:

    Oracle数据库:

    SQL> conn scott/oracle
    已连接。
    SQL> show user
    USER"SCOTT"
    
    SQL> create or replace synonym v$version for sys.v_$version;
    
    同义词已创建。
    
    SQL> select *from scott.v$version;
    
    BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    PL/SQL Release 11.2.0.4.0 - Production
    CORE	11.2.0.4.0	Production
    TNS for Linux: Version 11.2.0.4.0 - Production
    NLSRTL Version 11.2.0.4.0 - Production
    
    SQL> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    达梦数据库中查询:

    SQL> select * from v$version@linkodbc1;
    
    行号     BANNER                                                                      
    ---------- ----------------------------------------------------------------------------
    1          Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    2          PL/SQL Release 11.2.0.4.0 - Production
    3          CORE 11.2.0.4.0 Production
    4          TNS for Linux: Version 11.2.0.4.0 - Production
    5          NLSRTL Version 11.2.0.4.0 - Production
    
    已用时间: 512.946(毫秒). 执行号:2301.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    问题4:查询中文数据显示为问号

    DBLINK使用ODBC方式访问目的表时,中文显示为问号。

    image-20211026122203432

    isql直接访问:

    image-20211026122404623

    可以看到上面,isql直接访问Oracle和达梦通过ODBC数据源访问创建DBLINK访问Oracle时,中文会显示乱码,一般是与客户端字符集环境有关,可以通过设置NLS_LANG环境变量指定客户端字符集。如下:

    ##配置与Oracle数据库相同的NLS环境
    SQL> select * from v$nls_parameters;
    
    PARAMETER							 VALUE
    ---------------------------------------------------------------- ----------------------------------------------------------------
    NLS_LANGUAGE							 AMERICAN
    NLS_TERRITORY							 AMERICA
    NLS_CURRENCY							 $
    NLS_ISO_CURRENCY						 AMERICA
    NLS_NUMERIC_CHARACTERS						 .,
    NLS_CALENDAR							 GREGORIAN
    NLS_DATE_FORMAT 						 DD-MON-RR
    NLS_DATE_LANGUAGE						 AMERICAN
    NLS_CHARACTERSET						 ZHS16GBK
    NLS_SORT							 BINARY
    NLS_TIME_FORMAT 						 HH.MI.SSXFF AM
    
    PARAMETER							 VALUE
    ---------------------------------------------------------------- ----------------------------------------------------------------
    NLS_TIMESTAMP_FORMAT						 DD-MON-RR HH.MI.SSXFF AM
    NLS_TIME_TZ_FORMAT						 HH.MI.SSXFF AM TZR
    NLS_TIMESTAMP_TZ_FORMAT 					 DD-MON-RR HH.MI.SSXFF AM TZR
    NLS_DUAL_CURRENCY						 $
    NLS_NCHAR_CHARACTERSET						 AL16UTF16
    NLS_COMP							 BINARY
    NLS_LENGTH_SEMANTICS						 BYTE
    NLS_NCHAR_CONV_EXCP						 FALSE
    
    ##配置NLS_LANG环境变量,添加到.bash_profile中
    [dmdba@localhost bin]$ vim ~/.bash_profile   ---添加下面内容
    export NLS_LANG="AMERICAN_AMERICA.ZHS16GBK"
    
    [dmdba@localhost bin]$ source ~/.bash_profile
    [dmdba@localhost bin]$ env|grep NLS_LANG
    NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    生效后,再次使用isql进行查询正常

    [dmdba@localhost bin]$ isql -v ORA11 scott oracle
    +---------------------------------------+
    | Connected!                            |
    |                                       |
    | sql-statement                         |
    | help [tablename]                      |
    | quit                                  |
    |                                       |
    +---------------------------------------+
    SQL> select * from t1;
    +---------------------+-----------------------------------------+----+-----------------------------------------+
    | NAME                | AGE                                     | SEX| GRADE                                   |
    +---------------------+-----------------------------------------+----+-----------------------------------------+
    | 丽丽              | 18                                      || 1000                                    |
    +---------------------+-----------------------------------------+----+-----------------------------------------+
    SQLRowCount returns -1
    1 rows fetched
    SQL> quit
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    但是DBLINK中还是乱码

    image-20211026122607965

    原因

    由于DM数据库启动时未将NLS_LANG环境变量加载导致。

    如果在DM数据库启动时未加载到NLS_LANG环境变量,即使是disql窗口配置了NLS_LANG环境变量并生效也是无法正常显示中文的,所以在配置NLS_LANG环境变量生效后,需要在当前会话窗口重启DM数据库后才能正常显示中文。

    如下:

    情况1:配置NLS_LANG生效后启动DM数据库,然后disql窗口未配置NLS_LANG,查询正常正常

    image-20211028115634454

    image-20211028115701295

    情况2:DM数据库启动会话窗口未配置NLS_LANG,disql窗口配置了NLS_LANG之后,查询中文显示问号

    image-20211028115731897

    image-20211028115751478

    解决办法

    方法一:使用Oracle OCI的方式创建DBLINK。如果数据库启动时未加载Oracle OCI驱动,需要重启数据库加载Oracle OCI驱动。

    image-20211026123136131

    方法二:配置好NLS_LANG环境变量并生效后,在当前窗口重启DM数据库服务

    问题5:查询报错“字符串不完整”

    DBLINK使用ODBC方式创建,重启数据库之后,访问目的端表报错 “[-70037]:字符串不完整”。

    image-20211026125841557

    原因

    问题4:“查询中文数据显示为问号”

    解决办法

    同问题4:“查询中文数据显示为问号”

    问题六:使用select count()报错

    DBLINK使用ODBC数据源方式创建,无法使用count,直接报错。
    现象:

    image-20211026123436259

    使用OCI方式创建DBLINK,可以正常执行。

    image-20211026123545076

    使用isql直接访问Oracle数据库执行正常。

    image-20211026123752834

    解决办法

    第一种办法:升级数据库版本到2021年12月之后的版本。
    第二种办法:使用Oracle OCI的方式创建DBLINK。

    如果数据库启动时未加载Oracle OCI驱动,需要重启数据库加载Oracle OCI驱动。
    该问题以在后面版本中修复解决。

    更多资讯请上达梦技术社区了解:https://eco.dameng.com

  • 相关阅读:
    UE4 C++:TMap容器
    【HTML5入门指北】第一篇 初始HTML5
    CommunityToolkit.Mvvm8.1 消息通知(4)
    【力扣hot100】day1
    JAXB(Java Architecture for XML Binding)下载、使用
    MongoDB系列之添加账号和密码
    神经网络编译器TVM
    Tomcat深入浅出(一)
    .NET Task 揭秘(3)async 与 AsyncMethodBuilder
    基于C#的房屋租赁管理系统设计与实现
  • 原文地址:https://blog.csdn.net/Mrkill123/article/details/127459491