土耳其语 SQL 排序规则的问题(土耳其语“I”)

Posted

技术标签:

【中文标题】土耳其语 SQL 排序规则的问题(土耳其语“I”)【英文标题】:Problems with Turkish SQL Collation (Turkish "I") 【发布时间】:2009-04-23 07:31:05 【问题描述】:

我的 MSSQL 数据库设置为任何土耳其语排序规则时遇到问题。由于“土耳其语 I”问题,我们的查询中没有一个包含“i”的查询正常工作。例如,如果我们有一个名为“Unit”的表,其中定义了列“UnitID”,则查询“select unitid from unit”不再有效,因为“id”中的小写“i”与定义的大写字母不同我在“UnitID”中。错误消息将显示“无效的列名 'unitid'。”

我知道这是因为在土耳其语中,字母 i 和 I 被视为不同的字母。但是,我不确定如何解决此问题?遍历数据库中的所有 1900 SP 并更正“i”的大小写不是一种选择。

如有任何帮助,我们将不胜感激,甚至建议使用其他排序规则来代替土耳其语,但会支持其字符集。

【问题讨论】:

你能发布一个链接到描述“土耳其我问题”的页面吗? @Tomalak,看看这个页面:moserware.com/2008/02/does-your-code-pass-turkey-test.html 我知道那个页面。但我不确定你是否做对了。 “土耳其测试”是关于解析数据的,但您的问题描述听起来像是您在 SQL 查询文本中使用土耳其语 i - 在任何情况下都不应该这样做。 我们的前端应用程序正确解析数据,问题在于 SQL 存储的过程中不使用土耳其语 'I' 他们使用英语 'i' 和 'I' 但是当使用土耳其语排序规则时试图区分小写 i 和大写 I,因为它们被视为不同的字母......希望我能正确解释自己吗?谢谢! 土耳其语有 2 个“i”字符。 "ı" = "I" 和 "i"="İ" 这就是发生此问题的原因。如您所见,小写 I 是“ı”而不是“i”的大写。 【参考方案1】:

事实证明,最好的解决方案实际上是重构所有 SQL 和代码。

在过去的几天里,我编写了一个重构应用程序来修复所有存储过程、函数、视图、表名以保持一致并使用正确的大小写,例如:

select unitid from dbo.unit 

将改为

select UnitId from dbo.Unit

然后,应用程序还会检查代码并替换存储过程及其参数的任何出现,并更正它们以匹配数据库中定义的大小写。应用程序中的所有数据表都设置为不变的区域设置(感谢 FXCop 指出所有数据表..),这可以防止代码内的调用必须区分大小写。

如果有人想要该应用程序或对流程有任何建议,您可以通过 dotnetvixen@gmail.com 与我联系。

【讨论】:

...但您的字段是“UnitID”(大写“D”)【参考方案2】:

我在土耳其语支持下开发了这么多系统,正如你所说,这是众所周知的问题。

将数据库设置更改为 UTF-8 的最佳做法就是这样。它应该解决所有问题。

如果您想在 (ı-I,i-İ) 中支持区分大小写,那么您可能会遇到问题,而这在 SQL Server 中可能难以支持。如果整个入口来自 Web,请确保也是 UTF-8。

如果您将 Web UTF-8 输入和 SQL Server 设置保持为 UTF-8,那么一切都会顺利进行。

【讨论】:

【参考方案3】:

也许我不明白这里的问题,但这不是因为数据库区分大小写而您的查询不是吗?例如,在 Sybase 上,我可以执行以下操作:

USE master
GO
EXEC sp_server_info 16
GO

这告诉我我的数据库不区分大小写:

attribute_id   attribute_name     attribute_value 
          16   IDENTIFIER_CASE    MIXED

【讨论】:

感谢您的评论。我已将其设置为不区分大小写,但遗憾的是在土耳其语中,小 i 和大 I 实际上被视为完全不同的字符,因此它不是大小写问题!非常感谢【参考方案4】:

如果您可以更改正在使用的排序规则,请尝试使用 Invariant 语言环境。但请确保您不会影响其他内容,例如客户姓名和地址。如果客户习惯于搜索自己的姓名时不区分大小写,那么如果 ı 和 I 不再等价,或者 i 和 İ 不再等价,他们将不会喜欢这种方式。

【讨论】:

【参考方案5】:

您能否将数据库排序规则更改为默认值:这将使您的所有文本列都使用土耳其语排序规则?

查询会起作用,但数据会正常运行。理论上...

临时表和带有 varchar 列的表变量存在一些问题:您必须将 COLLATE 子句添加到这些问题

【讨论】:

不幸的是,我们所有的 varchar 列都设置为 database_default,因此如果将排序规则更改为普通的拉丁选项,那么 varchar 列将使用拉丁。我将尝试运行一个脚本来将所有 varchar 列上的排序规则设置为土耳其语,并将 db 排序规则设置为拉丁语,看看会发生什么!这是一个好主意,虽然不是很通用,因为理想情况下我们希望数据库能够处理任何不区分大小写的排序规则!感谢您的回复 更改数据库排序规则 (ALTER DATABASE) 应该使所有文本列保持原样。它只影响系统表和默认的 试过了,确实成功了。运行脚本将所有列排序规则更新为土耳其语,然后将 DB 排序规则设置为正常的拉丁排序规则,一切似乎都有效。最终重构了代码,正如我的回答中所见,因为这个解决方案不是很容易维护。但绝对在短期内有效。谢谢【参考方案6】:

我知道您不想通过所有存储过程来解决问题,但也许您可以使用重构工具来解决问题。我说看看SQL Refactor。我没有使用它,但看起来很有希望。

【讨论】:

这看起来是最好的建议。原发帖人说修复 1900 个存储过程不是一个选择,但保持 1900 个存储过程损坏不是一个好选择。【参考方案7】:

将机器的区域设置更改为英语(美国)完全可以节省时间!

【讨论】:

以上是关于土耳其语 SQL 排序规则的问题(土耳其语“I”)的主要内容,如果未能解决你的问题,请参考以下文章

用sql写给ascii的信

如何在 java 中将“i”与土耳其语 i 匹配?

mysql查询选择喜欢带有变音符号的土耳其字母

CSS:文本转换不适用于土耳其语字符

Android facebook-sdk 在土耳其语中崩溃

sql 删除土耳其人物