通过Oracle数据库链接进行复制时,为什么Char(1)会更改为Char(3)?

通过Oracle数据库链接进行复制时,为什么Char(1)会更改为Char(3)?,oracle,jdbc,dblink,Oracle,Jdbc,Dblink,我有两个数据库,我想将一个包含CHAR列的现有表从数据库a传输到数据库B 数据库A是Oracle 9i,编码为WE8ISO8859P1,并且包含一个表foo,其中至少有一列的类型为CHAR1 char。我无法更改数据库A上的表,因为它是第三方设置的一部分 数据库B是我自己的Oracle 10g数据库,出于各种原因使用AL32UTF8编码,我想将foo复制到这个数据库中 我设置了从数据库B到数据库a的数据库链接。然后发出以下命令: *从link.foo中选择*创建表格栏* 数据被很好地复制,但是当

我有两个数据库,我想将一个包含CHAR列的现有表从数据库a传输到数据库B

数据库A是Oracle 9i,编码为WE8ISO8859P1,并且包含一个表foo,其中至少有一列的类型为CHAR1 char。我无法更改数据库A上的表,因为它是第三方设置的一部分

数据库B是我自己的Oracle 10g数据库,出于各种原因使用AL32UTF8编码,我想将foo复制到这个数据库中

我设置了从数据库B到数据库a的数据库链接。然后发出以下命令:

*从link.foo中选择*创建表格栏*

数据被很好地复制,但是当我检查列的类型时,我注意到CHAR1 char已经转换为CHAR3 char,并且在数据库B中查询数据时,它都填充了空格

我认为在水下的某个地方,甲骨文混淆了它自己的字节和字符。CHAR1字节不同于CHAR1字符等。我已经读过所有这些

为什么数据类型会变为填充字符3字符?我如何阻止Oracle这样做

编辑:这似乎与在Oracle 9和10的两个特定补丁级别之间传输字符有关。看起来它真的是一只虫子。一旦我发现,我会发布更新。同时:不要像我描述的那样在数据库之间移动字符。VARCHAR2经过了良好的测试

编辑2:我找到了答案并发布在这里:
很遗憾,我不能接受自己的答案,因为我的问题已经解决了。

您需要了解WE8ISO8859P1 NLS和AL32UTF8之间的区别,前者将字符存储在一个字节中,后者将字符存储在四个字节中。您需要在Oracle国家语言支持NLS上花费一些宝贵的时间。Oracle会通过数据库链接自动进行转换,以提供帮助

从SQL提示符尝试以下操作:

ALTER SESSION NLS_NCHAR WE8ISO8859P1 
create table bar as select * from #link#.foo;

我要尝试的第一件事不是创建一个CTA表,而是创建一个列定义列表,并尝试插入前几千行。如果这没有成功,那么很清楚为什么。。。您可以很快确认Thomas Low完全正确。

这个问题是由Oracle错误处理基于原始列长度定义的不同字符集之间的字符转换引起的。当您以字节为单位定义字符类型列的大小时,Oracle不知道如何进行转换,因此无法进行转换。解决方案是始终以字符定义字符类型的长度

要更深入地解释这个问题以及我是如何解决这个问题的,请看

Yeh NLS是一种痛苦。我打赌你和医生们度过了一个安静的夜晚-我可以理解,如果原始类型是1个字符,它被更改为3字节或4字节。为什么要把1个字符改成3个字符呢?我已经读了32个小时了。所以我同意Dave的观点,我理解1个字符->3个字节。但是1个字符->3个字符并添加填充是完全错误的。如果我设置NLS\u NCHAR,我会将其设置为本地数据库的NLS。相反,您选择设置远程NLS。为什么?有趣的补充:由于某些原因,通过jdbc在会话中设置NLS_字符是不可能的。我在SquirreSQL中尝试了NLS_字符,但没有成功。我认为在线Oracle文档是一个巨大的交叉引用迷宫,它不包含清晰和有用的文本。