从sql server迁移到Oracle varchar长度问题

时间:2011-10-31 14:13:34

标签: sql-server oracle migration varchar nvarchar

我正面临一个试图从sql server迁移到oracle的奇怪问题。 在我的一个表中,我有NVARCHAR(255)定义的列 在阅读了一下后,我知道SQL服务器在oracle计数字节时计算字符数。 所以我在oracle中将我的表定义为VARCHAR(510) 255 * 2 = 510 但是当使用sqlldr从制表符分隔文本文件加载数据时,我得到错误,表明某些条目已经超出了此列的长度。 在使用以下命令检入sql server之后:

SELECT MAX(DATALENGTH(column))
FROM table

我得到的最大数据长度是510。

我确实使用了Hebrew_CI_AS collat​​iong,尽管我认为它不会改变任何东西.... 我检查了SQL Server,如果任何条目包含TAB但没有...所以我猜它不是一个损坏的数据.... 有谁有想法?

修改 进一步检查后,我注意到问题是由于数据文件(除了@Justin Cave post解决的问题。

我已将行分隔符更改为“^”,因为我的数据都不包含此字符和“| ^ |”作为列分隔符。

按如下方式创建控制文件:

load data
infile data.txt "str '^'"
badfile "data_BAD.txt"
discardfile "data_DSC.txt"
into table table
FIELDS TERMINATED BY '|^|' TRAILING NULLCOLS
(
     col1,
     col2,
     col3,
     col4,
     col5,
     col6
)

问题是我的数据包含<CR>,并且sqlldr期望<CR>上的流文件失败!我不想更改数据,因为它是一个文本数据(例子的错误消息)。

2 个答案:

答案 0 :(得分:5)

您的数据库字符集是什么

SELECT parameter, value
  FROM v$nls_parameters
 WHERE parameter LIKE '%CHARACTERSET'

假设您的数据库字符集是AL32UTF8,每个字符最多可能需要4个字节的存储空间(尽管几乎每个有用的字符都可以用最多3个字节的存储空间表示)。因此,您可以将列声明为VARCHAR2(1020),以确保您有足够的空间。

您也可以简单地使用字符长度语义。如果声明列VARCHAR2(255 CHAR),则无论需要多少空间,都将为255个字符分配空间。如果您将NLS_LENGTH_SEMANTICS初始化参数从默认BYTE更改为CHAR,则会更改默认值,以便将VARCHAR2(255)解释为VARCHAR2(255 CHAR)而不是VARCHAR2(255 BYTE)。请注意,即使您使用字符长度语义,VARCHAR2上的4000字节限制仍然存在。

如果您的数据包含换行符,是否需要TRAILING NULLCOLS参数?这意味着有时可以从逻辑行的末尾省略列。如果将可以省略的列与包含换行符的列和至少没有被可选的封装字符包围的数据组合在一起,那么对于我如何开始识别逻辑行的结束位置和开始位置并不明显。如果您实际上不需要TRAILING NULLCOLS参数,则应该能够使用CONTINUEIF parameter将多个物理行组合到一个逻辑行中。如果您可以更改数据文件格式,我强烈建议您添加可选的机箱字符。

答案 1 :(得分:-1)

NVARCHAR字段使用的字节数等于字符数加上 2的两倍(请参阅http://msdn.microsoft.com/en-us/library/ms186939.aspx),因此如果您创建VARCHAR你可能没问题。还有一些迹象表明某些字符集每个字符使用4个字节,但我没有发现希伯来语是其中一个字符集。