【问题标题】:Migrating from sql server to Oracle varchar length issues从 sql server 迁移到 Oracle varchar 长度问题
【发布时间】:2011-12-18 18:51:56
【问题描述】:

我在尝试从 sql server 迁移到 oracle 时遇到了一个奇怪的问题。 在我的一张表中,我有由NVARCHAR(255) 定义的列 读了一点后,我了解到当 oracle 计算字节时,SQL 服务器正在计算字符。 所以我在 oracle 中将我的表定义为 VARCHAR(510) 255*2 = 510 但是,当使用 sqlldr 从制表符分隔的文本文件中加载数据时,我收到错误消息,表明某些条目已超出此列的长度。 使用以下方法签入 sql 服务器后:

SELECT MAX(DATALENGTH(column))
FROM table

我知道最大数据长度是 510。

我确实使用了希伯来语_CI_AS 排序规则,即使我认为它不会改变任何东西.... 如果任何条目包含 TAB 但没有,我也检查了 SQL Server……所以我猜它不是损坏的数据…… 有人有想法吗?

编辑 经过进一步检查,我注意到问题是由于数据文件引起的(除了@Justin Cave 帖子解决的问题。

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

如下创建控制文件:

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> 上失败!!!!我不想更改数据,因为它是文本数据(例如错误消息)。

【问题讨论】:

  • 您可能会遇到另一个问题:Oracle 认为空白(零长度)字符串与 NULL 相同,而 SQL Server 认为它们不同。因此,如果您的原始 SQL Server 数据库有一个包含空格的非 NULL 字段,您将无法将此数据迁移到 Oracle 版本(除非您删除 Oracle 版本中的非 NULL 约束)。
  • @MusiGenesis 感谢您为我解决了这个问题,但我不明白它如何解决我的问题.... :(
  • 它不能解决你的问题——这就是为什么我把它作为评论而不是作为答案。

标签: sql-server oracle migration varchar nvarchar


【解决方案1】:

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

【讨论】:

  • 长度字节不会计入*char*字符串的定义大小。
【解决方案2】:

你的数据库字符集是什么

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 将多个物理行组合成一个逻辑行。如果您可以更改数据文件格式,我强烈建议您添加可选的附件字符。

【讨论】:

  • 一句警告:“与字符的最大长度无关,VARCHAR2 数据的长度不能超过 4000 字节。” download.oracle.com/docs/cd/E11882_01/server.112/e26088/…。换句话说,varchar2(2000 char) 不会容纳 2000 个字符,其中每个字符都是三个字节长。 OP 的问题中的专栏足够短,没有关系。
  • @NoamShaish - 添加了有关将多个物理记录组合成逻辑记录的信息。将来,如果您要问一个非常不同的后续问题,您可能想问一个单独的问题,而不是编辑您的初始问题。有一个专门针对 VARCHAR2 长度问题的问题和一个专门针对使用 SQL*Loader 将多个物理行组装成单个逻辑行的问题可能会更简洁。
猜你喜欢
  • 2015-04-17
  • 2010-10-14
  • 2011-06-09
  • 2018-04-07
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2015-08-22
  • 2014-02-09
相关资源
最近更新 更多