Oracle和SQL Server中的NVARCHAR之间的区别?

Zen*_*nil 18 database sql-server oracle nvarchar varchar2

我们正在将一些数据从sql server迁移到oracle.对于NVARCHAR在SQL Server中定义的NVARCHAR列,我们开始在Oracle中创建列,认为它们类似.但看起来它们不是.

我已经在stackoverflow上阅读了几篇帖子,并希望确认我的发现.

如果数据库字符集是AL32UTF8(在我们的情况下也是如此),Oracle VARCHAR2已经支持unicode.

SQLServer VARCHAR 支持unicode.SQLServer明确要求列在NCHAR/NVARCHAR类型中以unicode(特别是2字节UCS-2格式)存储数据.

因此,可以/应该将SQL Server NVARCHAR列迁移为Oracle VARCHAR2列是否正确?

Jus*_*ave 29

是的,如果您的Oracle数据库是使用Unicode字符集创建的,NVARCHAR则应在SQL Server中将其迁移到VARCHAR2Oracle中.在Oracle中,NVARCHAR存在数据类型,以允许应用程序在数据库字符集不支持Unicode时使用Unicode字符集存储数据.

但是,迁移中要注意的一件事是字符长度语义.在SQL Server中,NVARCHAR(20)为20个字符分配空间,在UCS-2中最多需要40个字节.在Oracle中,默认情况下,VARCHAR2(20)分配20个字节的存储空间.在AL32UTF8字符集,也就是可能只有足够的空间,6个字符,但最有可能将处理更多(单个字符AL32UTF8需要1至3个字节,你可能想声明您的Oracle类型,VARCHAR2(20 CHAR)这表明要分配无论需要多少字节,都可以容纳20个字符的空间.这比尝试解释为什么允许使用大约20个字符串而拒绝其他10个字符串更容易进行通信.

您可以在会话级别更改默认长度语义,以便您创建的任何表而不指定任何长度语义将使用字符而不是字节语义

ALTER SESSION SET nls_length_semantics=CHAR;
Run Code Online (Sandbox Code Playgroud)

这样可以避免CHAR每次定义新列时都键入内容.也可以在系统级别设置它,但NLS团队不鼓励这样做 - 显然,并非Oracle提供的所有脚本都已针对NLS_LENGTH_SEMANTICS已更改的数据库进行了全面测试.可能很少有第三方脚本.

  • @Zenil - 内部编码无法播放.嗯,有一些不同的Unicode标准修订版扩展了随着时间的推移定义的字符数,所以如果你碰巧从支持Unicode 6.2的数据库转到支持早期版本的数据库的某个字符.如果该字符不存在,那么您就会遇到问题,但无论数据是以UTF-8还是UTF-16或UTF-32或USC-2存储,都会出现问题.但这通常不是一个实际问题. (3认同)
  • “`在 SQL Server 中,NVARCHAR(20) 分配 20 个字符的空间`”:@JustinCave,这是不正确的。数字 20 并不代表字符数,而是代表“以字节对为单位的字符串大小”。这非常令人困惑,很多人都会犯这个错误,因为如果您使用代码点范围为 0-65535 的字符,则每个字符大小为 2 个字节,并且数量等于字符数。**但是**如果您使用 65536-1114111 范围内的字符,则每个字符大小为 4 个字节,并且使用 NVARCHAR(20) 仅为 10 个字符分配空间。 (3认同)