【YashanDB 知识库】oracle dblink varchar 类型查询报错记录
问题单:Oracle DBLINK 查询崖山 DB 报错
oracle 服务器上 ODBC 安装
unixodbc 安装:yum -y install unixODBC
mysql
配置安装对应版本的 odbc:
myodbc-installer -d -a -n "MySQL8.0" -t "DRIVER=/home/oracle/tools/mysql-connector-odbc-8.0.20/lib/libmyodbc8w.so;SETUP=/home/oracle/tools/mysql-connector-odbc-8.0.20/lib/myodbc8S.so"
yashandb
安装 yasdb-odbc
安装 yasdb-client
配置 odbc 驱动:
添加环境变量:
配置数据源
配置 oracle dblink 环境
监听文件配置
/data/app/oracle/product/19.3/dbhome_1/network/admin
vi listener.ora
新增:
坑 1:
配置这个后,oracle 的远程连接报错。
修改如下:
listener.ora 有三个部分
详解各个属性:
1、LISTENER 部分包含协议地址列表,每个实例一个入口,监听名称,可以配置多个监听,多个监听的端口号要区分开来
2、SID_LIST_LISTENER 部分标识全局数据库名称、标识监听程序正在服务的每个实例的 Oracle 软件主目录以及实例或 SID。
3、SID_LIST 描述用于静态数据库注册、保持和以前的版本兼容性以及供 Oracle Enterprise Manager 使用,因为我本地有三个数据库
把 SID_DESC 放到 SID_LIST_LISTENER 中
配置 tns 文件
vi tnsnames.ora
新增:
配置 odbc 监听
cd /data/app/oracle/product/19.3/dbhome_1/hs/admin
mysql
添加文件:
yashandb
重启监听
创建链接异构数据库连接
在 yashandb 和 mysql 上建表如下:
mysql
yashandb
问题原因
dblink 使用 odbc 连接其它数据库,如 yashandb、mysql 等
● 把其它数据库的 varchar 类型会变成 oralce 中的 nvarchar2 类型,如下组图 1。
● nvarchar2 类型 2 个字节存储一个字符,超过 varchar(2000)的字段类型因为超过了 4000 个字节,在 oracle 中变成了 long 类型,如下组图 2。
● long 类型不能在 where、group by、order by 中使用。
问题复现
组图 1:
mysql 中的表类型:
![](https://static001.geekbang.org/infoq/b3/b3ea7f76b4dd6e550ea214165ef0ee17.png)
oracle 中的表类型:
![](https://static001.geekbang.org/infoq/32/3206471bf6ad51c17efaca726b5e4534.png)
查询正常:
![](https://static001.geekbang.org/infoq/7a/7ae602b860ea2d80d26fbf1750ddbc47.png)
组图 2:
mysql 中的表类型:
![](https://static001.geekbang.org/infoq/c6/c67f46563bf468014f57792cde64bb40.png)
oracle 中的表类型:
![](https://static001.geekbang.org/infoq/24/24353d98d41fd4c03497c70c47ced152.png)
查询报错:
![](https://static001.geekbang.org/infoq/58/5876d38a117b288d10a094182b8b322a.png)
oracle long 类型限制
LONG 数据类型中存储的是可变长字符串,最大长度限制是 2GB。
对于超出一定长度的文本,基本只能用 LONG 类型来存储,数据字典中很多对象的定义就是用 LONG 来存储的。
LONG 类型主要用于不需要作字符串搜索的长串数据,如果要进行字符搜索就要用 varchar2 类型。
很多工具,包括 SQLPlus,处理 LONG 数据类型都是很困难的。
LONG 数据类型的使用中,要受限于磁盘的大小。
能够操作 LONG 的 SQL 语句:
Select 语句
Update 语句中的 SET 语句
Insert 语句中的 VALUES 语句
限制:
一个表中只能包含一个 LONG 类型的列。
不能索引 LONG 类型列。
不能将含有 LONG 类型列的表作聚簇。
不能在 SQLPlus 中将 LONG 类型列的数值插入到另一个表格中,如 insert into …select。
不能在 SQL*Plus 中通过查询其他表的方式来创建 LONG 类型列,如 create table as select。
不能对 LONG 类型列加约束条件(NULL、NOT NULL、DEFAULT 除外),如:关键字列(PRIMARY KEY)不能是 LONG 数据类型。
LONG 类型列不能用在 Select 的以下子句中:where、group by、order by,以及带有 distinct 的 select 语句中。
LONG 类型列不能用于分布查询。
PL/SQL 过程块的变量不能定义为 LONG 类型。
LONG 类型列不能被 SQL 函数所改变,如:substr、instr。 因为 long 类型的数值不能用 insert into … select 的方法插入,故我们要分两步走,先插入其它字段,最后再插入 long 类型字段,这可以通过过程来实现.
参考:oracle里long类型的总结_oracle long-CSDN博客
char 类型区别
char
1、char 的长度是固定的。比如说,你定义了 char(20),即使你你插入 abc,不足二十个字节,数据库也会在 abc 后面自动加上 17 个空格,以补足二十个字节;
2、char 是区分中英文的。中文在 char 中占两个字节,而英文占一个,所以 char(20)你只能存 20 个字母或 10 个汉字。
char 适用于长度比较固定的,一般不含中文的情况。
varchar/varchar2
1、varchar 是长度不固定的。比如说,你定义了 varchar(20),当你插入 abc,则在数据库中只占 3 个字节。
2、varchar 同样区分中英文。这点同 char。
3、varchar2 基本上等同于 varchar。它是 oracle 自己定义的一个非工业标准 varchar,不同在于,varchar2 用 null 代替 varchar 的空字符串。
varchar/varchar2 适用于长度不固定的,一般不含中文的情况。
nvarchar/nvarchar2
1、nvarchar 和 nvarchar2 是长度不固定的;
2、nvarchar 不区分中英文。比如说:你定义了 nvarchar(20),你可以存入 20 个英文字母/汉字或中英文组合,这个 20 定义的是字符数而不是字节数;
3、nvarchar2 基本上等同于 nvarchar,不同在于 nvarchar2 中存的英文字母也占两个字节。
大多数情况下,ORACLE 中的国家字符集是默认的,以下结论成立:
如果要省存储空间,建表时,字段内容里如果中文占了大多数,就用 nvarchar2 类型;如果内容是英文和数字为主的字符串,就用 varchar2 类型。
注意:
ORACLE 中的国家字符集,只有在数据类型为 NCHAR/NVARCHAR/NCLOB 时才会被使用,也就是前面带 N(national)的字符类型;
ORACLE 默认国家字符集为 AL16UTF16,完全对应 UNICODE 的 UTF-16 标准(有别于数据库字符集)
ORACLE 中的 UTF-8,不是标准的 UTF-8,而是 CESU-8。
参考:Oracle字段类型char、varchar2、nvarchar2的区别与使用_oracle varchar2-CSDN博客
规避方法
varchar 最大支持长度为 4000 字节,通过参数 MAX_STRING_SIZE 控制 MAX_STRING_SIZE 默认为 STANDARD,修改成 EXTENDED 支持 32K
修改步骤:
评论