接着昨天的话题,继续多语言界面: (上一篇)
6。关于文本排序:
不同语言对相同字符的排序可能是不同的,西方语言中,比如:瑞典语和德语都有字母“Ä ”,但瑞典语这个字母是在 Z 之后;德语是在 A 之后。西方语言的这种情况,我们接触的不多。
这次做的是简体中文、英语、日语三语言。比如中文和日文中都有汉字,但简体中文是按汉语拼音排序的,“学”(xue) 在 “生”(sheng) 之后;日语是按假名排序的,“学”(がく) 在 “生”(せい) 之前。
文本的排序,在 .NET 程序内部是跟区域代码关联的,具体到 ASP.NET 站点,我们在上一篇中为 Page.Culture 赋值 "zh-CN" 之后,如果比较“学”和“生”的话,就会按照已经指定的语言来比较、排序。
但这是在程序内部,可实际情况往往是:比如分页显示上万条数据时,我们是在数据库中排好顺序,只取出一页(20条或者40条或者 pageSize 条)的数据,返回给程序处理;如果我们在程序里只是对这 20条或者 40条数据排序的话,这只是将对已取出的这 20或40条记录排序,当然不是我们想要的效果。
也就是说这个排序规则需要在数据库端指定,在 Oracle 数据库的 PL/SQL 语言中,我们找到了
ALTER SESSION SET NLS_SORT = SCHINESE_PINYIN_M;
把这句话写在查询数据的存储过程/函数的最开始,则此存储过程/函数中的排序操作(ORDER BY ...)都将按汉语拼音排序;日语是
ALTER SESSION SET NLS_SORT = JAPANESE;
其他语言,我们可以使用默认的
ALTER SESSION SET NLS_SORT = BINARY;
传递一个代表不同区域的数字,在存储过程开始分别写上上面这句 SQL 即可达到预期的目的。
此处为错误!存储过程中不可以使用 ALTER SESSION ...,只能使用 NLS_SORT 函数!特修正:
SELECT ..... FROM .... WHERE ..... ORDER BY NLS_SORT(排序字段名, 'NLS_SORT=SCHINESE_PINYIN_M') DESC;
很遗憾,我在 SQL Server 的 T-SQL 语言中没有找到类似的操作(哪位知道的可以告诉我),据我目前所知:SQL Server 只支持的“静态”的排序规则,你可以给一个字符类型(char, varchar, text, nvarchar, ntext)的字段指定排序规则,但指定之后在存储过程中间不能改变这个规则,即一个字段只能按一种规则排序,不能动态改变。看来 SQL Server 暂时无法满足我们这个需求。
其他数据库的情况,尚不知晓,知道的朋友请留在下面,大家共同分享。
7。显示与程序内部处理的格式问题
比如,我们通过 Query String (查询字符串)传递一个日期参数到另一个页面,这时我们就应当使用和区域性无关的固定格式,如 DateTime.ToString("yyyyMMdd"),这样无论在何种区域性中我们都得到 20040911 的字符串,便于我们在另一侧“接收”。
也就是,内部处理需要通过文本传递时,使用和区域性无关的固定格式;而显示时使用和区域性相关的格式。
打印 | 张贴于 2004-09-11 21:27:00 | Tag:暂无标签
留言反馈
我明白你的意思,正因为你的文章是基于WEB的,至少对我个人来说是更有意义的。
我只是想说在PL/SQL过程或者函数中调用ALTER SESSION可能不符合ALTER SESSION本身的含义。
至于这个问题如何解决,我想方法应该有很多种。
其一. 你也许可以查一下诸如NLSSORT函数,这样可能就不用修改SESSION的设定了。
其二. 我想你是使用了ADO.NET或者Oracle内部提供的连接池来减少在接续方面的损失,如果自己维护一个连接池也许就会让实现方法有所改观。
另: 刚才找了一下,在Sql Server中,似乎下面的写法也可以做到(没有测试)。
例: 按照日文的排序规则
SELECT 。。。。。。
ORDER BY XXXXXX COLLATE JAPANESE_BIN
我想应该是这样的: 我这里是一个 Web 站点,不同的访问者偏好的语言、区域性是不同的,比如 14:05 时用户 A 访问了站点,调用存储过程时使用的是中文排序; 14:06 偏好日文的用户 B 使用了日文排序;14:07 用户 A 刷新了页面,又是中文排序;……
我想你应该知道我的意思了吧?Web 系统面对的是一群用户,而不是只有一个用户。
# 我只是用VC5做过支持日文和英文的系统,对与.NET相关部分只是读读手册的程度。
也许是我理解错了,不过让我鸡蛋里面挑下骨头。
似乎文中对ALTER SESSION的表现有些欠妥?
另外感觉只要你能保证是同一SESSION,就没有必要在每次调用过程、函数时执行?