Tsql 根据SQL Server中的不同排序规则对列进行排序

Tsql 根据SQL Server中的不同排序规则对列进行排序,tsql,multilingual,collation,Tsql,Multilingual,Collation,我有一个带有多语言CompanyName列的companys表(定义为nvarchar(512)) 我还有一个存储过程可以搜索并返回公司列表,它需要两个nvarchar参数——一个是搜索词,另一个是ISO语言代码 我希望能够返回搜索结果,并使用与第二个参数中提供的语言代码相匹配的排序规则进行排序,例如: SELECT * FROM dbo.Companies WHERE CompanyName LIKE '%searchstring%' ORDER BY CASE @lang

我有一个带有多语言CompanyName列的companys表(定义为nvarchar(512))

我还有一个存储过程可以搜索并返回公司列表,它需要两个nvarchar参数——一个是搜索词,另一个是ISO语言代码

我希望能够返回搜索结果,并使用与第二个参数中提供的语言代码相匹配的排序规则进行排序,例如:

SELECT * FROM dbo.Companies WHERE CompanyName LIKE '%searchstring%'
ORDER BY
    CASE @lang
        WHEN 'sv' THEN CompanyName COLLATE Sami_Sweden_Finland_100_CI_AI
        WHEN 'ch' THEN CompanyName COLLATE Chinese_Simplified_Pinyin_100_CI_AI
                ELSE CompanyName
    END
但是,当我尝试运行它时,会出现以下错误:

无法解决排序规则冲突 之间 “中文简体拼音100字” 以及"萨米(瑞典),"芬兰"和"萨米(芬兰)100(意大利)等 案例操作

这对我来说毫无意义——我并不是在排序规则之间排序,为什么会有排序规则冲突?这是一个相互排斥的选择

我尽量不太聪明,只使用动态sql,不幸的是,这似乎使数据库无法缓存执行计划,因此当表包含大约200万行时,查询时间将花费20秒以上(而不是1秒)


我确信区域性敏感排序肯定是一个常见问题,有人知道一个不涉及更改当前架构(例如,必须创建其他列)的好解决方案吗?

a列只能有一个排序规则。这个案例意味着你试图让多个相互冲突的人参与进来。试试这个:

SELECT * FROM dbo.Companies WHERE CompanyName LIKE '%searchstring%'
ORDER BY
    CASE @lang
        WHEN 'sv' THEN CompanyName ELSE '' END 
    END COLLATE Sami_Sweden_Finland_100_CI_AI,
    CASE @lang
        WHEN 'ch' THEN CompanyName ELSE '' END 
    END Chinese_Simplified_Pinyin_100_CI_AI

好的,我终于找到了这个问题的答案,多亏了@gbn,从我对这个问题的最初定义来看,你的解决方案绝对是正确的

然而,事实证明,我是在错误的假设下工作的,即应该避免使用动态SQL。为了让它工作,我必须添加一个值为的计算(和索引)列

CompanyName COLLATE [Collation_Name]
对于我需要排序的每个排序规则(我意识到我在最初的问题中说过我不想改变模式,但我真正的意思是我不想移动现有数据)

运行以下查询时

EXEC('SELECT TOP 10 * FROM dbo.Companies
      WHERE CompanyName LIKE ''%searchstring%''
      ORDER BY CompanyName COLLATE ' + @collation)
查询引擎在关联的计算列上提取索引,我得到一个快速响应。不幸的是,当使用@gbn提供的查询时,在计算列上创建的索引被忽略,从而导致性能下降


这让我非常惊讶,因为我一直认为动态SQL是一种邪恶,除非绝对必要(即当您的查询以无法参数化的方式变化时),否则应该避免使用动态SQL)

谢谢,这否定了使用动态SQL的必要性(虽然我仍然不明白为什么单个CASE语句中的不同排序规则会导致冲突-它只会对一个进行排序!)。现在的问题是SQL似乎没有将索引作为执行计划的一部分来提取。在上面的示例中,我创建了两个计算列(索引列)在CompanyName列上,分别使用瑞典语和拼音排序规则,这是在按CompanyName执行带有显式排序规则的ORDER时获取的,但不在上面的查询中。是否有方法显式告诉SQL使用索引?@Jonathan Hoult:不幸的是,没有。正如您所期望的,COLLATE子句会使索引无效。