2008-10-31 70 views
3

我有2个数据库,以及欲输送含有从数据库A到数据库B. CHAR列为什么在Oracle DBLINK上复制时,Char(1)变为Char(3)?

数据库A是Oracle 9i中,已编码WE8ISO8859P1现有的表,并包含一个表“foo”的用至少有1个CHAR类型的列(1个字符)。我无法更改数据库A上的表格,因为它是第三方设置的一部分。

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

我设置从数据库B数据库A.数据库链接然后我发出以下命令:

*创建表栏为SELECT * FROM#链接#包含.foo; *

的数据被复制但是当我检查列的类型时,我注意到CHAR(1个字符)已被转换为CHAR(3个字符),并且在查询数据库B中的数据时,它都填充了空格。

我觉得在水下的某个地方,Oracle混淆了它自己的字节和字符。 CHAR(1字节)与CHAR(1个字符)等不同。我已阅读了所有这些内容。

为什么数据类型更改为填充CHAR(3个字符),并且如何阻止Oracle执行此操作?

编辑:这似乎与在两个特定的Oracle 9和10的补丁级别之间传输CHAR有关。它看起来像是一个真正的bug。只要我发现我会发布更新。同时:不要像我描述的那样尝试在数据库之间移动CHAR。 VARCHAR2正常工作(测试)。

编辑2:我找到了答案,在这里贴吧:Why does Char(1) change to Char(3) when copying over an Oracle DBLINK? 太糟糕了,我不能接受我自己的答案,因为我的问题就解决了。

回答

3

此问题是由Oracle(mis)基于原始列长度定义处理不同字符集之间字符转换的方式引起的。当您以字节为单位定义字符类型列的大小时,Oracle不知道如何进行转换并对其进行转储。 解决方法是始终以字符定义字符类型的长度。

有关问题的更深入的解释,以及如何我想通了这一点看看 http://www.rolfje.com/2008/11/04/transporting-oracle-chars-over-a-dblink/

2

您需要了解WE8ISO8859P1 NLS(存储一个字节中的字符)和存储最多四个字节的字符的AL32UTF8之间的区别。您将需要花费一些高质量的时间与Oracle国家语言支持(NLS)Documentation。 Oracle会自动通过数据库链接进行转换,试图提供帮助。

尝试从SQL提示以下内容:

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

星爷NLS是一种痛苦。我敢打赌,你已经和文档分享了安静的夜晚。 ;-) – 2008-10-31 16:38:31

1

我想尝试不创建表作为CTAS但与列定义列表,并尝试执行前几的插入的第一件事千行。如果这样做没有成功,那么为什么......会很清楚,并且你很快就会确认托马斯·洛斯是否准确无误。

相关问题