Microsoft SQL Server 2000 的国际化功能(2)
2007-11-11 05:18:48 来源:WEB开发网在多个级别指定的排序规则
在 sql server(WINDOWS平台上强大的数据库平台) 2000 中,可以在以下级别指定排序规则:
- 服务器级别
- 数据库级别
- 列级别
- 表达式中
在服务器级别指定的排序规则
服务器级别是排序规则通常所处的级别,它在多数情况下是唯一需要设置的排序规则。如果您没有明确设置数据库级别的排序规则,当创建该排序规则后,它将作为服务器上所有数据库中所有排序规则的默认值。因为始终要为一个数据库提供一个排序规则,所以除非是在创建数据库时,否则决不会真正考虑服务器级别的排序规则。
您可以更改该排序规则,而无需使用“重建 Master”实用程序 (RebuildM.exe) 来重新运行 Setup。该实用程序位于 Program Files\Microsoft sql server(WINDOWS平台上强大的数据库平台)\80\Tools\BINN 目录。有关详细信息,请参见 sql server(WINDOWS平台上强大的数据库平台) Books Online for sql server(WINDOWS平台上强大的数据库平台) 2000 中的 "Rebuild master Utility"(重建 master 实用程序)主题。
您还可以使用 Transact-sql server(WINDOWS平台上强大的数据库平台)PROPERTY 函数在服务器上查询排序规则,例如:
SELECT CONVERT(char, SERVERPROPERTY('collation'))
数据库级别的排序规则
每个数据库都可以有一种唯一的排序规则,而排序顺序则在数据库级别设置。下面的图解(图 6)说明了使用 sql server(WINDOWS平台上强大的数据库平台) 企业管理器来设置排序规则的方法。
(WINDOWS平台上强大的数据库平台) 2000 的国际化功能(2)(图七)" />
图 6:使用企业管理器设置排序规则
您还可以使用 Transact-SQL 来设置排序规则顺序。例如,要按照捷克共和国的排序顺序和区分大小写及重音的形式创建一个新的数据库,可以使用如下语句:
USE masterGOCREATE DATABASE ProductsON( NAME = products_dat,FILENAME = 'c:\program files\microsoft sql server(WINDOWS平台上强大的数据库平台)\mssql(WINDOWS平台上强大的数据库平台)\data\products.mdf' )COLLATE Czech_CS_ASGO
有趣的是,您甚至可以使用 ALTER DATABASE 语句来更改现有数据库的排序规则(当使用 sql server(WINDOWS平台上强大的数据库平台) 企业管理器时,该语句不可用)。例如,以下语句将 Products 数据库的排序规则从 Czech_CS_AS 更改为 Czech_CI_AI (将区分大小写和重音更改为不区分大小写和重音):
ALTER DATABASE ProductsCOLLATE Czech_CI_AI
更改数据库排序规则之前的注意事项
要更改数据库的排序规则,必须符合以下所有条件:
- 不会有其他人正在使用该数据库。
- 没有依赖于数据库排序规则的架构绑定对象。符合条件的架构绑定对象包括以下任何内容:
- 用户定义的函数和用 SCHEMABINDING 创建的视图
- 已计算的列
- CHECK 约束
- 表值函数,它们使用从默认数据库排序规则继承的排序规则来返回包含字符列的表。
- 用户定义的函数和用 SCHEMABINDING 创建的视图
- 尝试更改数据库排序规则的行为不会导致任何系统名称的重复。这是很容易想象的,例如尝试将排序规则从 French_CI_AS 更改为 French_CS_AS(或将不区分大小写更改为区分大小写)。对于 sql server(WINDOWS平台上强大的数据库平台) 早期版本中的排序规则,可能有两个分别名为 Table1 和 TABLE1 的表;然而,对于 sql server(WINDOWS平台上强大的数据库平台) 2000 的排序规则,这种情形会导致重复。可能导致这种重复的对象包括:
- 对象名(如过程、表、触发器或视图)。
- 构架名(如组、角色或用户)。
- 标量类型名(如系统和用户定义的类型)。
- 全文目录名
- 对象中的列名或参数名。
- 表中的索引名。
- 对象名(如过程、表、触发器或视图)。
以上限制都具有实际的意义,它们将防止您执行会破坏数据或数据库的操作。实际上,有些人甚至认为这些规则不够严格! 如果 text、varchar 或 char 字段中包含数据并且列上没有显式的排序规则,那么更改数据库排序规则就会改变数据编码的解释方式,从而毁坏 ASCII 范围(包含在所有代码页中)外的所有字符。这样做是很危险的。相反,如果数据库包含的文本数据列不属于 Unicode 类型并且这些列没有它们自己的显式排序规则集(参见下面的在列级别指定的排序规则),您就应该尽量避免更改任何这些数据库的排序规则。
此外,您也可以使用 Transact-SQL DATABASEPROPERTYEX 函数来查找数据库的排序规则,例如:
SELECT CONVERT(char, DATABASEPROPERTYEX('pubs', 'collation'))
在列级别指定的排序规则
在 sql server(WINDOWS平台上强大的数据库平台) 2000 中,您可以更改特定列中文本的排序规则。这是很有用的,例如在需要对密码列强制区分大小写这种情况下。在其他情形下,可能会用到不同的语言列。例如,客户名可能需要以使用 Latin1_General 的 Unicode 来进行范围最广的适当排序,而产品名则可能会始终采用的是希腊语,在这种情形下,希腊语排序规则可能比较恰当。以下图解(图 7)显示了在使用 sql server(WINDOWS平台上强大的数据库平台) 企业管理器进行表设计的过程中的排序规则说明。
(WINDOWS平台上强大的数据库平台) 2000 的国际化功能(2)(图八)" />
图 7:使用企业管理器进行表设计时的排序规则的详细说明
当您单击“...”按钮时,将出现以下图解中所示的对话框。在该对话框(图 8)中,您可以选择一种排序规则。
(WINDOWS平台上强大的数据库平台) 2000 的国际化功能(2)(图九)" />
图 8:“排序规则”对话框
您还可以使用 Transact-SQL 设置来列级别的排序规则。在 CREATE TABLE 语句中,将 COLLATE 子句添加到列定义中即可。以下示例中的作业说明有一个用于阿拉伯语的排序规则集(不区分大小写、重音和假名类型)。
CREATE TABLE jobs(job_id smallintIDENTITY(1,1)Prima(最完善的虚拟主机管理系统)RY KEY CLUSTERED,job_desc varchar(50)COLLATE Arabic_CI_AI_KSNOT NULLDEFAULT 'New Position - title not formalized yet',)
您可以使用 ALTER TABLE 语句来更改具有新数据类型的列级别排序规则(ntext 或 text 列除外)。但是,您可以使用 sql server(WINDOWS平台上强大的数据库平台) 企业管理器更改 ntext 列的排序规则。这是因为 sql server(WINDOWS平台上强大的数据库平台) 企业管理器会创建一个 temp 表,将数据移动到新的 temp 表,删除旧表,使用新的排序规则创建一个新表,然后再将数据复制回新表。
在表达式中指定的排序规则
当您需要向不同国家的用户显示数据并希望按适当的区域设置进行排序时,可能会遇到许多情况。对于 sql server(WINDOWS平台上强大的数据库平台) 2000,您可以在表达式中指定排序规则。这种强大的新功能允许您以特定的方式进行排序,这样 ORDER BY 子句就可针对于具体的语言。
例如,以下查询按照名和姓对 Customers 表进行排序(使用立陶宛语排序顺序是排序规则差异的一个很好示例,因为字母 Y 在字母后排序的规则相当明显,很容易注意)。
SELECT*FROMtblCustomersORDER BYLastName COLLATE Lithuanian_AI_CI,FirstName COLLATE Lithuanian_AI_CI
您还可以参见 sql server(WINDOWS平台上强大的数据库平台) Books Online for sql server(WINDOWS平台上强大的数据库平台) 2000 中有关常规比较的示例,如:
SELECT*FROMTable1WHEREField1 = Field2 COLLATE Turkish_ci_ai
假定 Table1 没有显式的列级排序规则,那么这两列都将按土耳其语排序顺进行比较。要详细了解为什么会出现这种情况,请参见本文稍后的排序规则的优先规则。
COLLATE 关键字
使用 COLLATE 关键字的语法是:
COLLATE [<Windows_Collation_name>|<SQL_Collation_Name]
很难对排序规则的名称作出选择。关键字可以在数据库级别、列级别或在表达式中指定。通常,只要字段不是 Unicode 类型(ntext、nvarchar 或 nchar),就会使用先前将排序规则转换为代码页的步骤。
有两种类型的排序规则:
Windows 排序规则
这些规则是由 Windows 定义的。您完全有权指定是否区分大小写、重音、假名和宽度以及定义二进制排序。
SQL 排序规则
这些排序规则是由 sql server(WINDOWS平台上强大的数据库平台) 为解决遗留问题而定义的。您不具有配置这些排序规则的充分权限。
一般来说,您应该尽可能地使用 Windows 排序规则。以下图解(图 9)显示了一个排序规则可能会如何变化的简单示例。在该示例中使用的是 pubs 数据库。Y 是否出现在 I 和 J 之间或 X 和 Z 之间,取决于是否使用立陶宛语排序规则,这无疑会影响查询中各项的排序方式。
(WINDOWS平台上强大的数据库平台) 2000 的国际化功能(2)(图十)" />
图 9:排序规则对排序影响的示例
排序规则的优先规则
在 sql server(WINDOWS平台上强大的数据库平台) 2000 中,您可以在服务器、数据库和列级别以及在表达式中指定排序规则。这些排序规则是如何相互影响的?
这种相互影响需要遵循某些直接的规则,虽然这些规则看起来可能有些费解,但确实是必需的。下面显示了 A 和 B 作为要比较的两个不同部分的相互影响。
显式 B | 隐式 B | 默认值 | 无排序规则 | |
显式 A | 运行时错误 | 显式 A | 显式 A | 显式 A |
隐式 A | 隐式 B | 无排序规则 | 隐式 A | 无排序规则 |
默认值 | 隐式 B | 隐式 B | 默认值 | 无排序规则 |
无排序规则 | 隐式 B | 无排序规则 | 无排序规则 | 无排序规则 |
下面提供了该表中各项的定义。
显式 A/显式 B
为给定表达式显式定义的排序规则。
隐式 A/隐式 B
已经在列级别定义的排序规则。
默认值
正在使用的数据库级别排序规则。
无排序规则
两个操作符之间存在冲突;处理表达式时无排序规则。
正象您看到的那样,sql server(WINDOWS平台上强大的数据库平台) 无法处理表达式的仅有情况包括:当您显式定义两个不同且相互冲突的排序规则时,或当您设法比较两项却无法找到进行比较的任何共同点时。它们实际上并不是限制,而是可以理解的规则。sql server(WINDOWS平台上强大的数据库平台) 只需要您提供一些比较的依据。
例如,在创建表时考虑使用下面的 Transact-SQL 语句:
CREATE TABLE TestTab (id int,GreekCol nvarchar(10) COLLATE greek_ci_as,LatinCol nvarchar(10) COLLATE latin1_general_cs_as)INSERT TestTab VALUES (1, N'A', N'a')GO
该语句创建了一个包含以下两列的表:一列使用不区分大小写和区分重音的希腊语排序规则,而另一列使用区分大小写和重音的通用 Latin1 排序规则。
您可以尝试使用查询来显式比较这两列:
SELECT *FROM TestTabWHERE GreekCol = LatinCol
但是,该查询会返回一个错误:
Msg 446, Level 16, State 9, Server V-MICHKA3, Line 1无法解决等于运算的排序规则冲突。
之所以会出现此错误,是因为服务器无法使用不同的排序规则来比较两段文本。但是,如果您使用 COLLATE 关键字显式创建一个允许这两列兼容的表达式,则查询将以如下方式执行:
SELECT *FROM TestTabWHERE GreekCol = LatinCol COLLATE greek_ci_as
还需注意的是,尽管 LatinCol 通常有一个区分大小写的排序规则,但表达式不区分大小写的排序规则会将其覆盖,从而使“A”的大写和小写被视为等同。
COLLATE 关键字的限制
COLLATE 关键字及其相关功能是令人难以置信的。本文作者相信,在同时代的企业数据库产品中,它们也是无以伦比的。不过,它们仍存在以下列出的一些限制。请注意,这些限制都有解决办法。此处所述的限制有助于了解您可以直接执行哪些任务以及哪些任务需要一点额外的工作。
返回不完整的排序规则列表
fn_helpcollations 函数(请参见上文在列级别指定的排序规则中的图解)返回了完整的排序规则列表。但是,按照上文数据库级别的排序规则中所述对话框的内容,sql server(WINDOWS平台上强大的数据库平台) 完全可以列出一个区域设置(如阿尔巴尼亚语),并将标记的其余部分提供为选项,以最终返回完整的字符串。如果要为该功能提供一个用户界面,则必须执行一点额外的操作。
在列级别定义排序规则的问题
您每隔多久会遇到一个需要一种排序顺序(如 Latin1_General)的数据库和一个需要另一种排序顺序(如希腊语)的列?有时,这可能是一个相当关键的问题,但是在其他时候,如果数据库中的数据未使用单一的排序规则,那么该数据就可能是需要按多种排序规则进行排序的多种语言数据。由于可以定义多种排序规则并且每种排序规则都可以编制索引,所以您可以通过指定希腊语排序规则来访问希腊语数据,还可以使该查询成为索引搜索。
最后一个子句“使该查询成为索引搜索”是问题的关键。在以前提供的示例中,使用查询 ORDER BY 子句中的 COLLATE 表达式就可实现这种功能;但是,这并不是索引排序,因此对大型数据集而言,这种排序较慢。事实上,只有当列中没有单语言数据或数据库已取消标准化以便在不同列中存储不同语言时,列级排序规则才有意义。
LCID 和排序规则
Windows 使用区域设置 ID (LCID) 来定义排序。如果您正在对结果进行格式化,那么您可能已经有了现成的 LCID(或者,您可以通过指定 1024 或使用 Microsoft Visual Basic? 格式化函数来使用默认的 LCID,以完成您的工作)。事实上,如果您是在基于 Web 的 ASP 应用程序中进行这项工作,则可以使用 Microsoft Visual Basic Scripting Edition (VBScript) 中的 SetLocale 函数来更改要使用日期/时间、数字格式以及任何区域设置的货币格式首选项。不过,排序规则和 LCID 之间无法相互映射:由于 LCID 到排序规则是多对一的映射,您可以从一种排序规则中获得一个 LCID,但却无法从一个 LCID 中获得一种排序规则。
这样为什么不方便呢?好吧,设想您有一个多种语言网站,来自不同国家和地区的人们都可以访问该网站并查看产品信息。您可能已经将他们浏览器的 HTTP_ACCEPT_LANGUAGE 变量映射为 LCID,以使用 Session.LCID 属性对日期和货币值进行格式化,而且为了便于使用,您认为使用他们的区域设置进行排序是明智的选择。
要构建自己的映射函数来解决这个问题,请参见 sql server(WINDOWS平台上强大的数据库平台) Books Online for sql server(WINDOWS平台上强大的数据库平台) 2000 中的 "Rebuild master Utility"(Windows 排序规则指示器)主题中的转换表。
ISO 字符串和排序规则
您可以使用如下脚本来获取 VBScript 中的 HTTP_ACCEPT_LANGUAGE 变量:
Dim stLangstLang = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")
鉴于该值是许多 Web 开发人员在处理区域设置信息所拥有的唯一值,所以 VBScript SetLocale 函数不仅包含 LCID 值,而且直接接受该值。这意味着您不必执行将该值映射为 LCID 的中间步骤。由于 sql server(WINDOWS平台上强大的数据库平台)2000 无法接受象“en-us”(美国英语)这样的字符串并将其正确映射到 Latin1_General 排序规则,也无法接受象“vi”(越南语)这样的字符串并将其正确映射到越南语排序规则,因此您必须自己映射所有的字符串。
如何定义自定义排序规则?
看过无数排序规则选项后,许多开发人员通常会提出如何定义他们自己的排序规则这一问题。答案是他们不能定义自定义排序规则。如果排序规则不能添加到 Windows 2000 中,则同样不能添加到 sql server(WINDOWS平台上强大的数据库平台) 2000 中。这是因为排序规则主要用于定义对 Unicode 标准中每个已定义字符进行排序的方法,而并没有设计任何用户界面来让用户创建排序规则。
注意 所有新的 sql server(WINDOWS平台上强大的数据库平台) 排序规则都来自 Windows 中的信息,这就是将它们称作 Windows 排序规则的原因。
服务器和客户端之间的通信(代码页和排序规则问题)
在极少数的情况下,您使用 sql server(WINDOWS平台上强大的数据库平台) 执行的所有操作都在服务器所在的同一台计算机上进行,并且只使用 sql server(WINDOWS平台上强大的数据库平台) 工具,如 SQL 查询分析器或 sql server(WINDOWS平台上强大的数据库平台) 企业管理器。但在多数情况下,服务器将与其他服务器或客户端进行交互,或者可能使用一个或多个数据访问标准。您可能需要知道 sql server(WINDOWS平台上强大的数据库平台) 2000 是如何处理这些问题的。在此上下文中,与 sql server(WINDOWS平台上强大的数据库平台) 通信的是客户端。客户端有以下两种基本类型:
- Unicode 客户端:OLE DB 和 ODBC 3.7 版和更高版本
- 非 Unicode 客户端:ODBC 3.7 版和早期版本以及 DB-Library
开始使用非 Unicode 数据时所面临的一个重要问题是使用 ODBC 时,数据在代码页间进行转换的方式,或者数据与 Unicode 间进行转换的方式。当 SQL_COPT_SS_TRANSLATE 属性发送给 SQLSetConnectAttr 后,它可能会有两种设置:
- SQL_XL_OFF
驱动程序不将客户端和服务器间交换的字符数据中的字符从一个代码页转换到另一代码页。
- SQL_XL_ON
驱动程序将客户端和服务器间交换的字符数据中的字符从一个代码页转换到另一代码页。驱动程序会自动配置字符转换,从而确定了安装在服务器上的代码页以及正由客户端使用的代码页。
在默认情况下,SQL_XL_ON 是要使用的属性。您还可以使用 SQL-DMO TranslateChar 方法来设置 SQLServer 对象的 SQL_XL_ON 属性。通常情况下,无论您何时处理非 Unicode 数据,该默认值都会提供所需的行为(用于启用 auto_translate)。
客户端和服务器连接的可能情形以及一些相关问题将在下面的主题中讨论。
- ››sql server自动生成批量执行SQL脚本的批处理
- ››sql server 2008亿万数据性能优化
- ››SQL Server 2008清空数据库日志方法
- ››sqlserver安装和简单的使用
- ››SQL Sever 2008 R2 数据库管理
- ››SQL SERVER无法安装成功,sqlstp.log文件提示[未发...
- ››Sql Server中通过父记录查找出所有关联的子记录
- ››SqlServer触发器、存储过程和函数
- ››SQL Server 中的事务(含义,属性,管理)
- ››Sqlite数据库插入和读取图片数据
- ››Sql server 2005拒绝了对对象 'xx表' (数...
- ››Sql server 2005拒绝了对对象 'xx表' (数...
更多精彩
赞助商链接