SQL Server 2005 中的国际功能

SQL Server 2005 中的国际功能

简介

Microsoft SQL Server 2005 是在 SQL Server 2000 中引入的 Unicode XML 支持的基础上构建,并通过 SQL Server Management Studio Business Intelligence Development Studio 添加了一组全新的、功能强大的开发和查询工具。可靠的多语言功能使 SQL Server 2005 在支持国际操作和环境方面成为引人注目的数据库产品和应用程序平台。

本白皮书在全局上下文中提供了对这些功能的概述。它列出了与国际和多语言要求有关的功能,并说明了设计决策能够对项目的众多方面产生怎样的影响。

注意 本文使用以下国际字体来提供某些国际字符的示例:Arial Unicode MSLathaMangalPmingLiuGulimSimSun MS-Mincho。不安装这些字体不会对本文的有效性产生严重影响。

SQL Server 2005 中的 Unicode 支持

Unicode 支持是 SQL Server 2005 中多语言支持的基础。

Unicode 是由 Unicode Consortium(一个提倡为所有语言使用单一字符集的组织)创立的一项标准。SQL Server 2005 支持 Unicode 标准 3.2 版。Unicode 标准的 3.01 版与 ISO-10646(一项与 Unicode 中的所有码位均相符的国际标准)完全相同。

Unicode 的工作方式是,为每个字符提供一个唯一的码位,该码位与平台、程序或语言无关。支持 Unicode 的程序可以处理任何语言的数据。因为其设计宗旨是涵盖世界上所有语言的所有字符,所以不需要让不同的代码页来处理不同的字符集。

因为所有 Unicode 系统都统一使用相同的位模式来表示所有字符,所以从一个系统转到另一个系统时,不会出现字符转换不正确的问题。

管理国际数据库中的字符数据的最简单方法是始终使用 Unicode ncharnvarchar nvarchar(max) 数据类型,而不使用它们对应的非 Unicode 数据类型:charvarchar text。这样,客户端与所有其他客户端所看到的数据中的字符将是相同的。如果所有使用国际数据库的应用程序还使用 Unicode 变量来代替非 Unicode 变量,则不需要在系统中的任何位置执行字符转换。

注意 未来版本的 Microsoft SQL Server 中将删除 ntext 数据类型。

Unicode 码位及它们所代表的字符与用于可视呈现的字形是分开的。ISO 标准 (ISO/IEC 9541-1) 将字形定义为与具体设计无关的可识别抽象图形符号。因此,一个字符不必总是由相同的字形乃至唯一的字形来表示。所选择的字体决定将使用什么字形来表示特定码位或一系列码位。

编码

Unicode 将码位映射到字符,但实际上并不指定数据在内存、数据库或网页中的表示方式。这便是 Unicode 数据编码发挥作用的地方。有许多不同的 Unicode 编码。多半选择一种 Unicode 数据类型即可,不必为这些细节操心;不过,在以下情况下了解编码有重要意义:

应对可能以不同方式对 Unicode 进行编码的应用程序时

向其他平台(非 Microsoft Windows)或 Web 服务器发送数据时

导入其他编码的数据或将数据导出为其他编码时

Unicode 标准定义了其单一字符集的多种编码:UTF-7UTF-8UTF-16 UTF-32。本部分对这些常见的编码进行说明:

UCS-2

UTF-16

UTF-8

SQL Server 通常以 UCS-2 编码方案存储 Unicode。不过,许多客户端以另一种编码方案(如 UTF-8)来处理 Unicode。这种情况在基于 Web 的应用程序中经常出现。在 Microsoft Visual Basic 应用程序中,字符串以 UCS-2 编码方案来处理。因此,不需要显式地指定 Visual Basic 应用程序与 SQL Server 实例之间的编码方案转换。

SQL Server 2005 使用 Unicode (UTF-16) 来对 XML 数据进行编码。类型为 xml 的列中的数据以内部格式存储为二进制大型对象 (BLOB),以支持 XML 模型特征,如文档顺序和递归结构。因此,从服务器检索的 XML 数据会以 UTF-16 格式输出;如果想要为检索的数据使用其他编码,则应用程序必须对所检索的 UTF-16 数据执行必要的转换。

使用 UTF-16 编码是因为它可以处理 2 字节或 4 字节字符,并且处理是依照面向字节的协议进行的。这些特性使得 UTF-16 非常适合于遍历使用不同编码和字节排序系统的不同计算机。因为 XML 数据通常在网络上得到广泛共享,所以在数据库中及在将 XML 数据导出到客户端时保持默认的 UTF-16 存储格式是有意义的。

UCS-2

UCS-2 UTF-16 的前身。UCS-2 UTF-16 的不同之处是,UCS-2 是一种固定长度编码,它以 16 位值(2 个字节)表示所有字符,因此不支持补充字符。UCS-2 常与 UTF-16 发生混淆,UTF-16 用于在内部表示 Microsoft Windows 操作系统(Windows NTWindows 2000Windows XP Windows CE)中的文本,但 UCS-2 受到的限制更多。

Microsoft SQL Server 2000 Microsoft SQL Server 2005 中以 Unicode 存储的信息使用 UCS-2 编码,无论使用的是哪个字符,该编码都将每个字符存储为两个字节。因此,对拉丁语字母“A”的处理方式与对西里尔文字母 Sha ())、希伯来语字母 Lamed (ì)、泰米尔语字母 Rra (?) 或日语平假名字母 E (‚¦) 的处理方式是相同的。每个字母都有一个唯一的码位(对于上述字母,码位分别为 U+0041U+0248U+05DCU+0BB1 U+3048,每个四位十六进制数表示 UCS-2 使用的那两个字节)。

因为 UCS-2 只考虑了 65,536 个不同码位的编码,其本身无法处理补充字符,只能将补充字符视为未定义的 Unicode 代理项字符,这些字符组对后定义补充字符。不过,SQL Server 可以存储补充字符而不会有字符丢失或损坏的风险。通过创建自定义 CLR 函数,可以扩展 SQL Server 处理代理项对的能力。有关处理代理项对和补充字符的详细信息,请参阅本文后面的补充字符和代理项对部分。

注意 补充字符定义为具有补充码位的 Unicode 编码字符。补充码位的范围在 U+10000 U+10FFFF 之间。

UTF-8

UTF-8 是一种旨在以与计算机上的字节排序无关的方式来处理 Unicode 数据的编码方案。在处理 ASCII 及其他要求使用 8 位编码的面向字节的系统(例如,必须覆盖大量使用不同编码、不同字节顺序和不同语言的计算机的邮件服务器)时,UTF-8 会有帮助。尽管 SQL Server 2005 不以 UTF-8 格式存储数据,但它仍支持使用 UTF-8 来处理可扩展标记语言 (XML) 数据。有关详细信息,请参阅本文的 SQL Server 2005 中的 XML 支持部分。

其他数据库系统(例如,Oracle Sybase SQL Server)通过使用 UTF-8 存储来支持 Unicode。视服务器的实现方式而定,从技术上讲实现数据库引擎可能比较容易,因为服务器上的现有文本管理代码在一次处理一个字节的数据时并不要求进行重大更改。不过,在 Windows 环境中,UTF-8 存储有几个缺点:

组件对象模型 (COM) 仅在其 API 和接口中支持 UTF-16/UCS-2。因此,如果数据以 UTF-8 格式存储,必须始终进行转换。仅在使用 COM 时会出现此问题;SQL Server 数据库引擎通常不会调用 COM 接口。

Windows XP Windows Server 2003 的内核均采用 UnicodeUTF-16 Windows 2000Windows XP Windows Server 2003 的标准编码。不过,Windows 2000Windows XP Windows Server 2003 都可以识别 UTF-8。因此,在数据库中使用 UTF-8 存储格式需要进行许多额外的转换。通常,转换所需的额外资源不会影响 SQL Server 数据库引擎,但可能会影响许多客户端操作。

执行许多字符串操作时,UTF-8 的速度可能都会较慢。排序、比较及几乎任何字符串操作的速度可能都会下降,因为字符的宽度不固定。

UTF-8 往往需要 2 个以上的字节,并且增加的大小会占用更多的磁盘和内存空间。

尽管有这些缺点,但考虑到 XML 已成为一项重要的 Internet 通信标准这一事实,您可能希望考虑将默认编码设置为 UTF-8

注意 早期版本的 Oracle Java 也使用 UCS-2,它们无法识别代理项。Oracle Corporation Oracle 7 中开始支持将 Unicode 作为数据库字符集。Oracle 目前支持两种 Unicode 数据存储方法:(1) UTF-8 作为 CHAR VARCHAR2 字符数据类型以及所有 SQL 名称和文字的编码;(2) UTF-16 用于 NCHARNVARCHAR NCLOB Unicode 数据类型的存储。Oracle 允许同时使用这两种方法。

UTF-16

UTF-16 Microsoft 的编码标准,在 Windows 操作系统中 UTF-16 是一个扩展,其设计用途是处理附加的 1,048,576 个字符。对代理项范围的需要甚至在 Unicode 2.0 发布之前就已意识到了,因为事实清楚地表明,仅使用 65,536 个字符无法实现 Unicode 的用单 一码 位表示每种语言的每个字符的目标。例如,某些语言(例如,中文)至少需要那样多的字符才能对历史和文学表意文字等字符进行编码,这些字符尽管很少使用,但对出版和学术有着重要意义。下一部分提供了有关代理项范围的详细信息。

UTF-16 UCS-2 类似,也使用 little endian 字节顺序,在 Windows 上执行的任何操作都遵循该顺序。Little endian(与 big endian 相对)意味着低位字节存储在内存中的最低地址处。在操作系统级别字节的排序有重要意义。SQL Server 以及运行在 Windows 平台上的其他应用程序都使用 little endian 字节顺序。因此,0x1234 这样的十六进制词语以 0x34 0x12 形式存储在内存中。在某些情况下,可能需要显式地反转字节顺序以正确地读取字符的编码。SQL Server Integration Services 提供了用于转换 Unicode 文本字节顺序的函数。有关详细信息,请参阅本文的 SQL Server 2005 Integration Services 部分。

补充字符和代理项对

Microsoft Windows 通常使用 UTF-16 来表示字符数据。使用 16 位允许表示 65,536 个唯一字符。不过,即使是这么多的字符也不足以涵盖人类语言中使用的所有符号。在 UTF-16 中,某些码位紧接着前两个字节使用另一个码位,以将该字符定义为代理项范围的一部分。

Unicode 标准中,有 16 个字符平面,具有定义多达 1,114,112 个字符的潜力。平面 0(或称基本多语言块 (BMP))可以表示世界上的大部分书面文字、出版中使用的字符、数学和技术符号、几何图形、所有 100 Zapf Dingbat 以及标点符号。

BMP 之外,大部分平面中的字符仍未定义,但可以用来表示补充字符。补充字符主要用于历史和古典文学典籍,以协助处理中文、韩语和日语丰富文学遗产的编码。补充字符还包括古代北欧文字以及其他具有历史意义的文字、音乐符号等。

UTF-16 中,一对码位(称为代理项对)用于表示主字符集 (BMP) 之外的字符。代理项区是 Unicode 中从 U+D800 U+DFFF 的一个范围,其中包含 1,024 个低代理项值和 1,024 个高代理项值。高代理项(范围 U+D800 U+DBFF)和低代理项(范围 U+DC00 U+DFFF)相结合可以表示超过一百万个可能的字符。

仅具有代理项对的一半将视为无效;高代理项必须始终跟有低代理项,才算有效。这使得代理项的检查变为范围检查,它比检测 DBCS(双字节字符系统)字符所需的相当复杂的规则要简单。

尽管 UCS-2 不能识别代理项,但 SQL Server 2000 SQL Server 2005 都可以存储代理项对。SQL Server 将代理项对视为两个未定义的 Unicode 字符而非单一字符。此类应用程序通常称为代理中性代理安全,这意味着它们不具备固有的与数据进行交互的能力,但至少可以做到存储的数据不会丢失。

作为对照,能够识别代理项的应用程序不仅可以识别代理项对,还可以处理组合字符和需要特殊处理的其他字符。编写良好的应用程序可以检测到分开的代理项,并且只通过几个子例程就可以将它们重新组合。可以识别代理项的应用程序包括 Microsoft Word Internet Explorer 5 及更高版本。

SQL Server 中处理补充字符时,请记住以下几点:

因为代理项对被视为两个独立的 Unicode 码位,所以 nvarchar(n) 的大小必须是 2,以容纳单一补充字符(换言之,代理项对所需的空间)。

不支持在元数据(例如,数据库对象的名称)中使用补充字符。一般来说,元数据中使用的文本必须符合标识符的规则。

标准字符串操作不能识别补充字符。SUBSTRING(nvarchar(2),1,1) 之类的操作仅返回补充字符代理项对的高代理项。LEN 函数为遇到的每个补充字符返回两个字符的计数:一个计数对应高代理项,一个计数对应低代理项。不过,可以创建能够识别补充字符的自定义函数。

对补充字符的排序和搜索行为可能会随排序规则的不同而发生变化。在新的 90_and BIN2 排序规则中,可以正确地对补充字符进行比较,而在早期排序规则和标准 Windows 排序规则中,所有补充字符的比较都视同所有其他补充字符的比较。例如,默认的日语和朝鲜语排序规则不处理补充字符,而 Japanese_90 Korean_90 则会进行处理。

 

组合字符

组合字符是与其他字符一起使用以修改其外观或含义的字符。组合的字符会形成单一字形。例如,欧洲语言中使用的音调符号便是组合字符,可以作为字符加音调符号的形式或预构成字符的形式出现。

.NET Framework 中,将组合字符的顺序视为文本元素,即显示为单个字符的文本单元。文本元素有别于排序元素。例如,在某些排序规则中,字母“CH”不是组合字符;它们是两个独立的文本元素,但可以将它们视为一个排序元素。

注意 SQL 函数的做法有所不同,它通常将组合字符与补充字符一视同仁:它们将组合字符作为两个独立的 Unicode 码位进行处理。

组合字符映射到排序元素的方式取决于 Unicode 标准和排序规则这两者。某些组合字符始终被视为等同于它们的变体形式,无论它们包括多少不同的码位(例如,拉丁文字母加音调符号被视为等同于包括音调符号的预构成字符),而在某些排序规则中,可以根据音调符号是否存在以不同方式对字符串进行排序或比较。

组合字符最初是在 Unicode 2.0 中定义的。有关详细信息,请参阅论述特殊区域和格式字符 Unicode 4.0.1 规范部分Unicode Consortium 还发布了专门针对组合字符及其处理的 FAQ。有关在 .NET Framework 中处理组合字符的方法的详细信息,请参阅《.NET Framework 开发人员指南》中的标准化

GB18030 的支持

GB18030 (GB18030-2000) 是中华人民共和国 (PRC) 颁布的一项针对中文字符编码的独立标准。它对扩展代码页和与 Unicode 的映射表都做了规定。官方要求从 2006 8 1 日起,在 PRC 境内销售的所有软件产品都必须支持此字符集。GB18030 一致性包括对支持一些以前并不支持的语言(例如,藏文、蒙文、彝文和维吾尔文)的要求。

GB18030 中,字符可以是 12 4 个字节。代理项对用于支持 GB18030 4 字节序列与 Unicode 的映射。

SQL Server 2005 通过在采用 GB18030 编码的字符从客户端应用程序进入服务器时对它们进行识别来提供对这些字符的支持。SQL Server 2005 会在本地对这些字符进行转换,并将它们存储为 Unicode 字符。这些字符存储在服务器中后,在对它们执行的所有后续操作中均将它们视为 Unicode 字符。GB18030 不具有系统区域设置;它只有一个代码页标识符,以实现与 Unicode 之间的相互转换。Microsoft 针对 GB18030-2000 的代码页标识符为 54936

使用 GB18030 字符时,请记住这些字符可以在排序和比较操作中使用,但如果使用的是 SQL Server 90 之前的排序规则,将只能基于这些字符的码位而不能基于其他有语言意义的方式进行比较。因此,在 ORDER BYGROUP BY DISTINCT 等操作中使用 GB18030 字符时,尤其是在同一操作中同时包括 GB18030 字符和非 GB18030 字符时,应谨慎行事。要支持有意义的使用 GB18030 字符的字符串比较,请使用新的 SQL Server 90 排序规则版本(以添加到其名称中的 90 后缀表示)。例如,请使用 Chinese_PRC_90 排序规则,而不使用 Chinese_PRC 排序规则。

要启用对 GB18030 标准的支持,可以安装一个支持软件包,该软件包可以从 Microsoft 产品帮助和支持门户下载,其中包括支持 GB18030 Unicode 之间转换所需的字体文件和库。该支持软件包是一个可以在 Windows XP Windows 2000 上安装的单一全球二进制。不过,系统必须安装可选的东亚语言支持。Windows Vista 中包括了对 GB18030 标准的支持,其中包括针对中国少数民族语言(如藏文、蒙文、彝文和维吾尔文)的字体和键盘布局。这些语言均使用中文 (PRC) 区域设置。

注意Vista 中不支持某些将 GB18030 字节转换为 Unicode 字符的函数,如 BytesToUnicode。在 Vista 中将 GB18030 字节转换为 Unicode 字符时,请使用 MultiByteToWideChar 函数。

SQL Server 2005 中的数据类型

本部分介绍 SQL Server 2005 中的新数据类型,并说明与使用 SQL Server 2005 数据类型存储国际数据相关的问题。

Unicode 文本类型:charvarchartextvarchar(max)

当处理以 charvarcharvarchar(max) text 数据类型存储的文本数据时,需要考虑的最重要限制因素是,系统只能验证来自单一代码页的信息。(您可以存储来自多代码页的数据,但不建议这样做。)用于验证和存储数据的确切代码页取决于列的排序规则。如果尚未定义列级排序规则,则使用数据库的排序规则。要确定给定列所用的代码页,可以使用 COLLATIONPROPERTY 函数,如以下代码示例所示:

SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI_KS_WS', 'CodePage')

936

 

SELECT COLLATIONPROPERTY('Latin1_General_CI_AI', 'CodePage')

1252

 

SELECT COLLATIONPROPERTY('Hindi_CI_AI_WS', 'CodePage')

0

最后一个示例返回 0 (Unicode) 作为印地语的代码页。此示例说明了一个事实,即许多语言环境(例如格鲁吉亚语和印地语)都没有代码页,因为他们仅使用 Unicode 排序规则。那些排序规则不适用于使用 charvarchar text 数据类型的列,并且某些排序规则不受支持。

重要信息 SQL Server 2005 中,使用 varchar(max) 数据类型而非 text 数据类型。未来版本的 Microsoft SQL Server 将删除 text 数据类型。

当必须将 Unicode 数据插入到非 Unicode 列时,通过使用 WideCharToMultiByte API 和与排序规则关联的代码页,会在内部将列从 Unicode 转换成非 Unicode。如果在给定代码页上无法表示某字符,则用问号 (?) 替换该字符。因此,如果数据内随机出现问号,则充分说明数据由于未指定的转换而被破坏。这也充分说明转换为 Unicode 数据类型对应用程序很有好处。

如果使用排序规则不支持的非 Unicode 类型的字符串文字,则首先会使用数据库的默认代码页转换字符,该代码页源自数据库的默认排序规则。

可能遇到的另一个问题是,当代码页中未包含希望支持的所有字符时无法存储数据。多数情况下,Windows 会将特定代码页视为最适合代码页,这意味着无法保证利用该代码页可以处理所有文本,它只是可以利用的最佳选择。这种情况一个例证是阿拉伯语脚本:它支持多种语言,其中包括俾路支语、柏柏尔语、波斯语、克什米尔语、哈萨克语、吉尔吉斯语、库尔德语、普什图语、信德语、维吾尔语、乌尔都语以及更多语言。除 Windows 代码页 1256 中所定义阿拉伯语中的那些字符之外,所有这些语言还有其他字符。如果试图在具有阿拉伯排序规则的非 Unicode 列中存储这些额外字符,则这些字符会被转换成问号。

 

Unicode 文本类型:ncharnvarcharnvarchar(max)ntext
SQL-92
规范定义了以“N”(表示国家数据类型)开头的数据类型,但并未特别要求将这些数据类型用于 Unicode;这些数据类型的实际定义留给了数据库平台或开发人员。在 SQL Server 2000 SQL Server 2005 中,这些数据类型的定义方式等效于 UCS-2UCS-2 是一种 Unicode 编码。但是,当处理其他数据库服务器时,要知道“N”数据类型并不专门表示 Unicode,这一点非常重要。将“N”数据类型定义为 Unicode 这一决定特定于 Microsoft SQL Server

nvarchar(max) 数据类型是 SQL Server 2005 中的新数据类型,它最多容纳二十亿字节 (GB) 数据,是 ntext 数据类型的首选替代方法。

重要信息在 SQL Server 2005 中,使用 nvarchar(max) 数据类型而非 ntext 数据类型。未来版本的 Microsoft SQL Server 将删除 ntext 数据类型。

为存储复杂脚本(例如印地语和泰米尔语),请确保数据以正确顺序排序。许多语言(例如泰米尔语),都指定在呈现文本时重新排序某些字母;因此,文本存储在内存中的逻辑顺序可能不同于将在用户界面中所呈现的顺序。对于任何复杂的脚本语言(其中包括所有印度语、阿拉伯语、波斯语、希伯来语及其他语种),都始终应以正确的逻辑顺序存储数据。此类数据的实际呈现是一个单独的问题(请参阅本文的用户界面中的多语言数据部分)。

尽管“N”列可以支持任何语言或语言组合的数据,但排序数据时,只能选择单个排序规则。要了解有关如何选择排序规则的更多信息,请参阅本文的排序规则部分。本文先前提到的任何代码页限制都不适用于 Unicode 列。

SQL Server 2005 中,可以创建附加函数以使用补充字符来改进字符串操作和排序规则行为。例如,Microsoft SQL Server 2005 StringManipulate 示例说明了能够识别补充字符的字符串处理。此示例展示了如何实现五个 Transact-SQL 字符串函数,这些函数提供与内置字符串函数相同的字符串操作函数,只是使用附加的能够识别补充字符的能力来处理 Unicode 和补充字符字符串。

CLR 数据类型
Microsoft SQL Server
使您通过定义 SQL Server 编程过程中使用的自定义数据类型,能够扩展 SQL 类型系统。这些用户定义的类型适合创建自定义日期、时间、货币和扩展的数值类型,或适合已编码或加密的数据。

用户定义的类型 (UDT) 可用于定义表中列的类型,或用于在 Transact-SQL 语言中定义变量或例程参数。用户定义类型的实例可以是表中的一列、批处理中的变量、函数或存储过程、或是函数或存储过程的参数。用户定义的类型作为任何一种 CLR 语言的托管类实现,然后使用 SQL Server 注册。

可以使用用户定义的类型来扩展服务器的标量类型系统,从而在 SQL Server 数据库中启用 CLR 对象的存储。UDT 可以包含多个元素,且可以具有所定义的特殊行为。这一点使它们不同于传统的别名数据类型,后者由单一 SQL Server 系统数据类型组成。例如,《SQL Server 2005 联机丛书》中的 Currency UDT 示例支持在特定语言的货币系统中处理大量货币。必须定义两个字段:一个是 CultureInfo 的字符串值,用于指定货币的来源(例如 en-us);另一个是用于 CurrencyValue 的十进制值,用于表示货币量。

由于系统会将 UDT 视为一个整体进行访问,因此将它们用于复杂数据类型可能会对性能造成负面影响。使用传统的行或表通常是构建复杂数据的最佳方法。《SQL Server 2005 联机丛书》包括多个说明如何创建和使用自定义的用户定义类型的示例。SQL Server 2005 UTF8String 示例说明了如何实现用户定义的数据类型,该数据类型会扩展数据库的类型系统,进而能够存储 UTF8 编码的值。新类型也实现了代码在 Unicode 字符串和 UTF8 之间的来回转换。

XML 数据类型
利用 XML 数据类型可以在 SQL Server 数据库中存储 XML 段或文档。XML 数据类型的实例可以是表中的列、函数、或存储过程参数,或是函数或存储过程中的变量。此外,通过指明为 XML 实例数据提供验证约束和类型信息的相关 XML 架构,可以特殊化 XML 数据类型。

通过使用内置 XML 查询方法对 XML 数据类型的实例执行操作。这些方法接受适合于 XML 数据的查询和数据操作语句。随后就可以针对存储在 XML 数据类型变量或列中的 XML 来指定查询 (XQuery),然后(使用插入、更新或删除)将更新应用到 XML 实例中。还可以使用 XSD 创建 XML 列的索引,这将改进查询性能。

有关 xml 数据类型,以及 SQL Server 2005 中支持处理 XML 数据的功能的详细信息,请参阅本文的 SQL Server 2005 中的 XML 支持部分。

日期/时间类型:datetimesmalldatetime
SQL Server 2000
SQL Server 2005 中使用的日期和时间数据类型定义如下:

datetime

公历中的日期和时间数据从 1753 1 1 日到 9999 12 31 日,精确到秒的三百分之一(相当于 3.33 毫秒或 0.00333 秒)。

smalldatetime

公历中的日期和时间数据从 1900 1 1 日到 2079 6 6 日,精确到分。对于带有 29.998 秒或更小秒数的 smalldatetime 值,向下取整为最接近的分;对于带有 29.999 秒或更大秒数的 smalldatetime 值,向上取整为最接近的分。

Microsoft SQL Server 会拒绝超出这些范围的数据。实际数据在内部存储为两个整数,分别表示相关的日期和时间(其中 4 字节整数为 datetime 值,2 字节整数为 smalldatetime 值)。

所存储的数据既不表示本地时间也不表示通用时间,并且不包含时区信息。如果需要将日期转换为通用时间,可以使用 UTC 日期函数之一。当前 UTC 时间从运行 Microsoft SQL Server 实例的计算机上获得,即根据该计算机操作系统中的当前本地时间和时区设置获得。由于值没有特定于语言环境的固有格式设置,所以由开发人员根据需要来定义转换。SQL Server 支持多种特定于语言环境的不同转换,这些转换可在服务器上执行而不必依赖于来自开发人员的自定义解决方案。通过 CONVERT 函数可以访问这些数据样式,它将利用数据类型、表达式以及可选样式,如下表所示。

带百位 不带百位 标准 输入(转换为 datetime 型数据)/输出(转换为 text 型数据)
0
100
 -
 
默认

 mon dd yyyy hh:miAM
(或 PM
 
101
 1
 
美国
 mm/dd/yy
 
102
 2
 ANSI
 yy.mm.dd
 
103
 3
 
英国/法国
 dd/mm/yy
 
104
 4
 
德国
 dd.mm.yy
 
105
 5
 
意大利
 dd-mm-yy
 
106
 6
 -
 dd mon yy
 
107
 7
 -
 Mon dd, yy
 
108
 8
 -
 hh:mm:ss
 
9
109
 -
 
默认 + 毫秒

 mon dd yyyy hh:mi:ss:mmmAM
(或 PM
 
110
 10
 
美国
 mm-dd-yy
 
111
 11
 
日本
 yy/mm/dd
 
112
 12
 ISO
 yymmdd
 
13
113
 -
 
欧洲默认 + 毫秒

 dd mon yyyy hh:mm:ss:mmm(24h)
 
114
 14
 -
 hh:mi:ss:mmm(24h)
 
20
120
 -
 ODBC
 
规范
yyyy-mm-dd hh:mi:ss(24h)
 
21
121
 -
 ODBC
规范 + 毫秒

 yyyy-mm-dd hh:mi:ss.mmm(24h)
 
126
 -
 ISO8601
(无空格)
 yyyy-mm-dd Thh:mm:ss:mmm
 
130
 -
 
科威特(回历)
 dd mon yyyy hh:mi:ss:mmmAM
 
131
 -
 
科威特(回历)
 dd/mm/yy hh:mi:ss:mmmAM
 

以下示例显示如何使用 CONVERT 函数以特定样式表示当前日期:

SELECT CONVERT(char, GETDATE(), 100) AS [100]
RETURNS:
Aug 16 2000 11:50AM

随后可采用与以下类似的方式将数据由字符串转换为日期值:

SELECT CONVERT(datetime, 'Aug 16 2000 11:50AM', 100) AS [100]
RETURNS:
100
2000-08-16 11:50:00.000

如果采用样式 130(科威特或回历)将数据转换为 char 数据类型,若排序规则不是使用代码页 1256 进行 Unicode 转换的阿拉伯排序规则之一,则数据可能会损坏。例如,图 1 显示了已转换为 char 数据类型的列以及已转换为 nchar 数据类型的另一列。在此示例中,客户端计算机使用 EN-US 区域设置。因此,当尝试使用 char 数据类型时,会将阿拉伯字符转换为问号,而如果使用 nchar 数据类型,则会显示阿拉伯字符。

 

1. 对日期/时间数据使用 CONVERT

但是,由于查询编辑器中的限制,即使使用 nchar 表示的字符串仍不会象在阿拉伯语客户端计算机上那样以正确格式显示。图 2 显示实际回历日期字符串应有的显示效果。

 

2. 回历日期字符串

阿拉伯语无法正确呈现的原因是,复杂的脚本(例如阿拉伯语)中具有控制数据如何呈现的定型规则。对于双向 (BIDI) 语言(例如希伯来语),定型会导致所有数据被反转。在阿拉伯语中,定型具有很显著的作用,因为字母的实际形状会根据周围字母发生更改。在 Windows 2000 以后的 Windows 版本、或是 Windows 2000 以前任何支持阿拉伯语的 Windows 版本中没有这个问题。

此外,所返回的日期字符串会在需要双向的情况下引发问题,因为应用程序(例如 Internet Explorer)所使用的双向文本的布局规则会使日期以图 3 中的方式显示。

 

3. 双向日期字符串示例

这个显示顺序 (dd hh:mi:ss yyyy mon :) 很明显不是所期望的顺序;可将这个问题视为 CONVERT 函数中 130 样式的一般性限制。可以通过在字符串前添加适当的 Unicode 控制字符来解决这个问题,如以下查询所示:

SELECT NCHAR(8207) + CONVERT(nchar, GETDATE(), 130)

NCHAR 函数根据传入 Unicode 代码点返回字符;8207 或十六进制 0x 200F 是从右到左标记 (RLM),这会使字符串得以正确显示。

性能和存储空间
如果使用其中一种 Unicode 数据类型来定义列,则可能会遇到以下与存储空间和速度有关的问题。

存储空间增加
Unicode
数据类型每个字符使用两个或更多个字节,而非 Unicode 数据类型为所有非 DBCS 文本使用一个字节,为使用 DBCS 的亚洲语言使用两个字节。因此,除非您的数据使用其中一种亚洲代码页,否则在转换到 Unicode 时,将要使用两倍的空间来存储数据。升级现有数据库或为新项目确定适当的数据类型时,必须对更大的存储空间需求加以考虑。如果只将数据存储在位于单个(非亚洲)代码页的列中,则您可能更愿意不使用 Unicode,以便节省磁盘上和内存中的空间。不过,Unicode 转换的优点通常会胜过存储上的负面影响。

注意存储亚洲 DBCS 数据时,SQL Server 2005 使用的 UCS-2 编码方法往往比许多其他数据库程序使用的 UTF-8 方法更有效率。这是因为 UTF-8 使用三个字节来存储大多数亚洲语言字符,而 UCS-2 只使用两个字节(补充字符和组合字符除外)。另一方面,对于非 DBCS 语言(例如基于 ASCII 的字符),UTF-8 通常每个字符仅使用一个字节,而 UCS-2 使用两个字节。

速度问题
使用 Unicode 数据类型对性能的影响较为复杂。您必须考虑以下问题:

如果是在 Windows XPWindows Server 2003 Windows Vista 上运行,操作系统要求使用 Unicode 数据;因此在许多情况下,在显示数据或使用操作系统服务时,必须对非 Unicode 列进行转换。
 
处理本机 DBCS 数据格式时,加载更大量数据可能需要更多的时间。

 
如果是在实例之间、数据库服务器产品之间工作,或是与其他应用程序交换数据,则转换的数量可能会影响性能。

 
如果处理的是亚洲语言,则与语言特有的 DBCS 代码页相比,Unicode 的速度更快。这是因为 DBCS 数据没有固定的宽度;它是双字节和单字节字符的混合体。

 
如果处理的是非亚洲语言,则对 Unicode 数据的排序速度将慢于对非 Unicode 数据的排序速度。

 
二进制是最快的排序顺序,而且区分大小写,但它可能会生成无法预料的排序顺序。如果选择二进制排序顺序,将无法使用区分大小写、区分重音、区分假名和区分全半角选项。

重要信息 要现实地评估性能,必须在 Unicode 和非 Unicode 应用场景中都进行测试。
 


迁移系统表中的元数据信息
SQL Server 2005
中的系统表以 Unicode 存储系统表中的所有数据(包括对象的标识符)。这会使数据库和列之间使用不同排序规则时出现问题的几率降至最低水平。

如果是从 SQL Server 2000 迁移到 SQL Server 2005,唯一的重大变化是 SQL Server 2000 为标识符中的有效字符列表使用 Unicode 2.0 标准,而 SQL Server 2005 支持 Unicode 3.2 版本的标准。

可以直接将 SQL Server 2000 Service Pack 3 (SP3) 或更高版本的实例,以及 SQL Server 7.0 SP4 或更高版本的实例升级到 SQL Server 2005。可以通过安装程序执行大多数升级操作;不过,某些组件支持或要求在运行安装程序后迁移应用程序或解决方案。


排序规则
排序顺序是数据库定义中一个非常重要,但又经常被忽视的部分。用户往往想当然地按其自己的字母表进行排序。不过,某些语言(例如,希腊语、俄语和泰语)使用不同的字母表。某些语言(例如,日语)使用多个字母表,而且排序规则复杂。即便是在欧洲语言中,处理个别字符的方式也存在很大差异。例如,西班牙语用户希望看到的是,字母组合“ch”作为单个字符排序在字母“h”之后。

基本排序通过排序规则发挥作用,排序规则控制排序顺序以及其他行为。可以通过创建索引来优化排序。

排序与称为字符串标准化的技术协同工作。此类标准化与数据库开发人员所熟悉的标准化的意义不同。字符串标准化指的是比较两个字符串以便对它们进行排序的方法:例如,您可以指定是否应将不同的假名类型视为等同,或是否应忽略重音。

对于非 Unicode 列,排序规则还有一个非常重要的意义:排序规则指定数据的代码页,因此确定了可以表示哪些字符。在 Unicode 列之间移动数据时不需要进行特殊转换或字符映射;但数据在非 Unicode 列之间移动时常会发生错乱或损坏,或根本无法显示。

SQL Server 6.5 和更早版本中的排序规则
SQL Server 6.5 版及更早版本中,排序规则用于指定一般情况下语言所使用的代码页。存在许多与不同排序顺序有关的限制。例如,如果使用 Latin-1,则只能支持西欧语言。这些排序规则还对可以在单个 SQL Server 实例中表示的不同区域设置的数量有限制。换言之,只能存储或显示在特定区域中使用的语言。要使用其他语言,需要建立单独的数据库乃至单独的服务器。

在后续版本的 SQL Server 中非 Unicode 字段的排序规则也存在这些问题。

SQL Server 7.0 中的排序规则
SQL Server 7.0
规定每个服务器使用一个 Unicode 排序规则和一个非 Unicode 排序规则。非 Unicode 排序规则定义为代码页和排序顺序的组合。通常,每个代码页都可以支持多个排序顺序;例如,拉丁语通常允许区分大小写排序和不区分大小写排序。简体中文允许按笔画和拼音进行排序。

Unicode 排序规则中,可以在列中包含任何语言的任何字符,而所提供的各种排序规则的设计用途便是确保能够正确地处理任何排序规则特定的差异。换言之,选择最合适的排序规则来为用户提供他们所需要的数据。例如,通用 Unicode 排序规则让您可以对波斯语数据进行排序。

Unicode 排序规则由一个区域设置和几个比较样式组成。区域设置通常根据国家/地区或文化区域来命名。它们根据该区域中的标准对字符进行排序。Unicode 排序规则仍然为采用 Unicode 标准的所有字符提供排序顺序,但所指定的区域设置享有优先权。任何不具有受支持的唯一 Unicode 排序规则的区域设置都应使用通用 Unicode 排序规则。

通用 Unicode 排序顺序不仅可以正确地处理数据,还可以正确地处理以下语言的排序:南非荷兰语、阿尔巴尼亚语、阿拉伯语、巴斯克语、白俄罗斯语、保加利亚语、英语、法罗语、波斯语、传统格鲁吉亚语、希腊语、希伯来语、印地语、印度尼西亚语、马来西亚语、俄语、塞尔维亚语、斯瓦希里语和乌尔都语。

SQL Server 7.0 中的一个重要变化是,提供了一个与操作系统无关的字符串比较模型,以使从 Windows 95 Windows 2000 的所有操作系统之间的排序规则均一致。此字符串比较代码所基于的便是 Windows 2000 为其自己的字符串标准化而使用的代码,在所有计算机上和所有版本的 SQL Server 中都封装成相同的代码。

SQL Server 2000 中的排序规则
SQL Server 2000 中,对排序规则模型进行了更改,以消除两个不同排序规则系统 Windows SQL Server 排序规则之间的不一致。要处理对排序规则的所有新要求,需要一个更灵活的模型。SQL Server 2000 中还需要一些新排序规则来处理非 Unicode 列的代码页。

为应对这些需求,设计了单一且一致的模型来处理 Unicode 和非 Unicode 排序。这些排序规则中的每一个都与帮助定义排序规则是否区分大小写、重音、全半角或假名类型的后缀相组合。附录 A 包含一个表,列出了这些后缀。这 17 个后缀与 SQL Server 2000 中支持的 40 种语言进行适当组合后,一共创建了 680 Windows 排序规则。

用于排序规则的语言名称是随机的,选择它们是为了表示非 Unicode 数据的每个唯一受支持的代码页及所有数据的排序顺序。在许多情况下,可以完整地在单一代码页上表示多个语言,或按另一语言使用的同一排序顺序进行处理,在这些情况下,会从列表中删除其他语言。

SQL Server 2005 中的排序规则
SQL Server 2005
支持 Microsoft Windows 操作系统所支持的所有语言。这意味着 SQL Server 2005 增加了对 Windows Server 2003 Windows XP 中新排序规则和更新排序规则的支持。(这些排序规则作为 SQL Server 2005 安装程序的一部分进行安装。可以在安装期间控制服务器和数据库排序规则的选择。对操作系统的更新不会影响 SQL Server 中使用的排序规则。)

新排序规则的一个重要部分是支持补充字符的东亚排序规则。还增加了对补充字符(基于码位)的字符串比较的支持,并引入了二进制标志 (BIN2) 以支持真正的码位比较。

二进制排序规则根据每个字符的位模式对 SQL Server 中的数据进行排序和比较。SQL Server 中的每个二进制排序规则都映射到某个特定的区域设置和 ANSI 代码页,并且每个都执行区分大小写和区分重音的数据排序。二进制排序规则所提供的数据排序速度最快。

二进制选项 (_BIN) 根据为每个字符定义的位模式对 SQL Server 表中的数据进行排序和比较。二进制排序顺序区分大小写并区分重音。二进制也是速度最快的排序顺序。如果不选择此选项,SQL Server 将遵循关联语言或字母表的字典中定义的排序和比较规则。

二进制码位 (_BIN2) 选项基于 Unicode 数据的 Unicode 码位对 SQL Server 表中的数据进行排序和比较。对于非 Unicode 数据,二进制码位将使用与二进制排序完全相同的比较。使用二进制码位排序顺序的优点是,在比较排过序的 SQL Server 数据的应用程序中不需要对数据重新排序。因此,二进制码位排序顺序会简化应用程序开发,并可能会提高性能。

附录 E 包含 SQL Server 2005 中进行了更新的排序规则的列表。除非需要向后兼容 SQL Server 2000 或更早版本,否则最好使用更新的排序规则。

SQL Server 2005 中的排序规则包括以下排序类型:Windows 排序规则和 SQL 排序规则。

Windows 排序规则
Windows
排序规则基于关联的 Windows 区域设置定义字符数据的排序规则。(Windows 区域设置的数量多于 SQL Server Windows 排序规则的数量。)基础 Windows 排序规则指定应用字典排序时所使用的字母表或语言,以及用于存储非 Unicode 字符数据的代码页。在 SQL Server 中,Windows 排序规则与一系列后缀相组合,以根据是否区分大小写、重音、假名和全半角来额外定义排序和比较规则。完整的 Windows 排序规则名称由排序规则指示符和比较样式组成。

Windows 排序中,非 Unicode 数据的比较和排序是使用与 Unicode 数据相同的算法来实现的。这使得 SQL Server 中的各数据类型保持一致,还为开发人员提供了使用 SQL Server 所使用的相同规则(即,调用 Microsoft Win32 API CompareStringW 函数)在其应用程序中对字符串进行排序的功能。

二进制排序规则
二进制排序规则根据区域设置和数据类型定义的编码值顺序对数据进行排序。SQL Server 中的二进制排序规则定义要使用的区域设置和 ANSI 代码页,从而强制执行二进制排序顺序。由于二进制排序规则相对简单,因此在实现更高的应用程序性能方面有帮助。对于非 Unicode 数据类型,数据比较基于 ANSI 代码页中定义的码位。对于 Unicode 数据类型,数据比较基于 Unicode 码位。对于有关 Unicode 数据类型的二进制排序规则,在数据排序中不考虑区域设置。例如,在 Unicode 数据上使用 Latin_1_General_BIN Japanese_BIN2 时,所产生的排序结果完全相同。这是因为该排序规则将 Unicode 作为 Unicode 进行比较,将非 Unicode 数据作为二进制进行比较。

SQL Server 2000 中,二进制排序规则会对 Unicode 数据执行不完全的码位对码位比较。第一个字符作为 WCHAR 进行比较,随后进行逐字节的比较。为确保向后兼容性,将不会更改现有二进制排序规则语义。

SQL Server 2005 中的二进制排序规则包括先前的 BIN 排序规则和一组新的纯码位比较排序规则。客户可以选择迁移到新的二进制排序规则以利用真码位比较,而且他们应在开发新应用程序时利用新的二进制排序规则。新的 BIN2 后缀用于标识实现新码位排序规则语义的排序规则名称。此外,还增加了对应于新二进制排序的 BIN2 的新比较标志。

SQL Server 会根据系统区域设置自动建议默认排序规则。仅在您安装的 SQL Server 必须与另一 SQL Server 实例使用的排序规则设置相符,或该排序规则设置必须与另一计算机的 Windows 系统区域设置相符时,才应更改 Windows 默认排序规则的设置。

如果需要处理补充字符,请将默认排序规则更改为支持对补充字符执行排序和比较操作的其中一个更新的排序规则。这些比较仅基于码位,而不基于其他在语言上有意义的方法。只有 90 排序规则版本(以它们名称后面添加 90 后缀来表示)支持这些操作。例如,使用 Japanese_90 代替 Japanese 排序规则。如果不使用可识别补充字符的排序规则,则在 ORDER BYGROUP BY DISTINCT 等操作中使用补充字符时,尤其是在同一操作中既包括补充字符又包括非补充字符时,请小心行事。

SQL Server 排序规则
SQL Server
排序规则提供了与早期版本 SQL Server 的排序顺序兼容性。(有关 SQL Server 排序规则的完整列表,请参阅“SQL Server 2005 联机丛书中的 SQL 排序规则名称。)SQL Server 排序规则基于非 Unicode 数据的旧有 SQL Server 排序顺序,例如,由 SQL Server 定义的 char varchar 数据类型。非 Unicode 数据的字典排序规则与 Windows 操作系统提供的任何排序例程均不兼容,但 Unicode 数据的排序与特定版本的 Windows 排序规则兼容。因为 SQL Server 排序规则为非 Unicode 数据和 Unicode 数据使用不同的比较规则,因此对于相同数据的比较可能会看到不同的结果,具体视基础数据类型而定。

升级 SQL Server 实例时,可以指定 SQL Server 排序规则以与现有 SQL Server 实例兼容。因为 SQL Server 实例的默认排序规则是在安装期间定义的,所以在下列情况下谨慎地指定排序规则设置有重要意义:

您的应用程序代码在某一方面依赖先前 SQL Server 排序规则的行为。
 
您要将 SQL Server 2005 复制与现有 SQL Server 6.5 SQL Server 7.0 系统一起使用。

 
您必须存储反映多种语言的字符数据。

 

如果您的数据库中混有 Unicode 和非 Unicode 列,则应主要使用 Windows 排序规则。Windows 排序规则会将基于 Unicode 的排序规则应用于 Unicode 和非 Unicode 数据。这意味着 SQL Server 会在内部将非 Unicode 数据转换成 Unicode 数据,以执行比较操作。这使得 SQL Server 中的各数据类型保持一致,并为开发人员提供了使用 SQL Server 所使用的相同规则在其应用程序中对字符串进行排序的功能。

相反,通过为 Unicode 数据使用相应的 Windows 排序规则,SQL 排序规则将非 Unicode 排序规则应用于非 Unicode 数据,将 Unicode 排序规则应用于 Unicode 数据。此差异可能会导致对相同字符的比较得出不一致的结果。因此,如果您的数据库中混有 Unicode 和非 Unicode 列,则它们全部都应使用 Windows 排序规则进行定义,以便对 Unicode 和非 Unicode 数据使用相同的排序规则。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值