修改搜索以使其在 SQL Server 中不区分重音

Posted

技术标签:

【中文标题】修改搜索以使其在 SQL Server 中不区分重音【英文标题】:Modify search to make it Accent Insensitive in SQL Server 【发布时间】:2012-07-22 19:48:21 【问题描述】:

我有一个当前排序规则为 French_CI_AS 的数据库,这意味着搜索不区分大小写,但区分重音。我的印象是,将数据库的排序规则更改为 French_CI_AI 可以解决我的问题,所以我做到了。但是,我仍然无法进行简单的搜索工作 Accent-Insensitive。我查了一下,表排序规则是French_CI_AI,可能是随着数据库一起改变的。

是否有某种方法可以使所有数据库上的 Accent 不敏感搜索成为可能?或者有没有办法以这种方式进行一次搜索?我只有一两个需要它的存储过程,所以我可以这样做。

如果有任何区别,我要查找的数据类型都是 nvarchar(n)s。

谢谢

【问题讨论】:

您确定 具有您期望的排序规则吗?更改数据库不会返回并更改所有现有列。 我不知道列本身有排序规则。我会检查的。谢谢 它只适用于一列,所以我现在要做的就是浏览我用来搜索的所有列,这并不多。谢谢。当然,如果您想要功劳,您可以发表评论作为答案! 【参考方案1】:

首先,更改数据库排序规则不会影响表中现有的列,但会影响新创建的表和列。这是在数据库中创建新对象时使用的默认排序规则。

因此,您要做的就是查找所有现有列并更新当前排序规则。

您可以使用 sql 游标并查询所有表和列并更新特定类型或列名的排序规则。

举例:

1)您更改未来对象的排序规则

USE master;
GO
ALTER DATABASE databasename COLLATE French_CI_AI ;
GO

2) 手动更改特定列的列排序规则

 ALTER TABLE tablenameX ALTER COLUMN LastName varchar(100) COLLATE French_CI_AI NULL
 ALTER TABLE tablenameY ALTER COLUMN FirstName varchar(100) COLLATE French_CI_AI NULL

3) 生成带光标的sql脚本

您需要决定更改排序规则的列。它可以是类型、名称或特定表。

您可以从查看您拥有的字符类型开始并在示例中替换它们,请参见列光标。

从 information_schema.columns 中选择不同的 DATA_TYPE

你可以参考这篇文章:

http://www.codeproject.com/Articles/302405/The-Easy-way-of-changing-Collation-of-all-Database

declare @CollationName as nvarchar = 'Latin1_General_CI_AS'

declare @tablename as nvarchar(100) = ''
declare @sqltext as nvarchar(100) = ''
declare @columnname as nvarchar(200) = ''
declare @DataType as nvarchar(100) = ''
declare @CharacterMaxLen as int = 0
declare @IsNullable as bit = 0

DECLARE MyTableCursor Cursor
FOR 
SELECT * from information_schema.TABLES
            WHERE TABLE_TYPE = 'BASE TABLE'
OPEN MyTableCursor
WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE MyColumnCursor Cursor
        FOR 
        SELECT COLUMN_NAME,DATA_TYPE, CHARACTER_MAXIMUM_LENGTH,
            IS_NULLABLE from information_schema.columns
            WHERE table_name = @TableName AND  (Data_Type LIKE '%char%' 
            OR Data_Type LIKE '%text%') AND COLLATION_NAME <> @CollationName
            ORDER BY ordinal_position 
        Open MyColumnCursor

        FETCH NEXT FROM MyColumnCursor INTO @ColumnName, @DataType, 
              @CharacterMaxLen, @IsNullable
        WHILE @@FETCH_STATUS = 0
            BEGIN
            SET @SQLText = 'ALTER TABLE ' + @TableName + ' ALTER COLUMN [' + @ColumnName + '] ' + 
              @DataType + '(' + CASE WHEN @CharacterMaxLen = -1 THEN 'MAX' ELSE @CharacterMaxLen END + 
              ') COLLATE ' + @CollationName + ' ' + 
              CASE WHEN @IsNullable = 'NO' THEN 'NOT NULL' ELSE 'NULL' END
            PRINT @SQLText 

        FETCH NEXT FROM MyColumnCursor INTO @ColumnName, @DataType, 
              @CharacterMaxLen, @IsNullable
        END
        CLOSE MyColumnCursor
        DEALLOCATE MyColumnCursor

FETCH NEXT FROM MyTableCursor INTO @TableName
END
CLOSE MyTableCursor
DEALLOCATE MyTableCursor

【讨论】:

【参考方案2】:

您可以让搜索使用您想要的任何排序规则,例如

WHERE column COLLATE FRENCH_CI_AI LIKE '%something%' COLLATE FRENCH_CI_AI

但是,我怀疑如果您确实修复了该列(当您更改数据库排序规则时没有发生这种情况),它会更好地工作。忽略任何约束和其他依赖项,如何解决这个问题的简短答案:

ALTER TABLE dbo.foo ADD newcol NVARCHAR(32) COLLATE FRENCH_CI_AI;

UPDATE dbo.foo SET newcol = oldcol;

ALTER TABLE dbo.foo DROP COLUMN oldcol;

EXEC sp_rename N'dbo.foo.newcol', N'oldcol', 'COLUMN';

【讨论】:

以上是关于修改搜索以使其在 SQL Server 中不区分重音的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 如何更改我的视图,使其在插入表时不会产生重复?

用前导零填充字符串,使其在 SQL Server 2008 中的长度为 3 个字符

如何放置时间戳以使其在保存时不会重复

我在哪里创建 .ebextensions 以使其在 AWS Elastic Beanstalk 中工作

如何隐藏 DefaultTableModel 中的特定列以使其在表中显示?

如何更改我的 C++ 代码以使其在 C 中可用?