Используя TSQL, CAST() с COLLATE не является детерминированным. Как сделать его детерминированным? Что такое обходной путь?

У меня есть функция, которая включает в себя:

SELECT @pString = CAST(@pString AS VARCHAR(255)) COLLATE SQL_Latin1_General_Cp1251_CS_AS

Это полезно, например, для удаления акцентов во французском языке; Например:

UPPER(CAST('Éléctricité' AS VARCHAR(255)) COLLATE SQL_Latin1_General_Cp1251_CS_AS)

дает ELECTRICITE.

Но использование COLLATE делает функцию недетерминированной, и поэтому я не могу использовать ее как вычисляемое постоянное значение в столбце.

Q1. Есть ли другой (быстрый и простой) способ удалить подобные акценты с помощью детерминированной функции?

Q2. (Дополнительный вопрос) Причина, по которой я делаю этот вычисляемый постоянный столбец, заключается в поиске. Например, пользователь может ввести фамилию клиента как «Гагне», «Гагне», «Гагне» или «Гагне», и приложение найдет ее, используя сохраненный вычисляемый столбец. Есть лучший способ это сделать?

РЕДАКТИРОВАТЬ: Использование SQL Server 2012 и SQL-Azure.


person Frank Monroe    schedule 02.10.2013    source источник
comment
С вопросом такого уровня лучше задать вопрос на dba.stackexchange.com.   -  person Scott Chamberlain    schedule 02.10.2013
comment
может быть, эта ссылка вам пригодится, она гласит, что в последнем абзаце он имеет дело с тем, что вы хотите youdidwhatwithtsql.com/comparing-accented-strings-with-tsql/849   -  person DrCopyPaste    schedule 02.10.2013
comment
К вопросу 2. Рассмотрите возможность использования полнотекстового поиска и создайте полнотекстовый каталог без учета диакритических знаков.   -  person Keith    schedule 02.10.2013
comment
Д-р: Спасибо за ссылку - отличный сайт SQL. Кейт: Насколько я понимаю, вы не можете использовать полный текст в SQL Azure — это недавно изменилось?   -  person Frank Monroe    schedule 03.10.2013


Ответы (2)


Вы обнаружите, что на самом деле он детерминирован, он просто ведет себя по-разному в зависимости от символа, который вы пытаетесь сопоставить.

Проверьте страницу кодировки Windows 1251, чтобы узнать о допустимых и недопустимых символах.

Вот диаграмма сопоставления для Cyrillic_General_CI_AI. Это кодовая страница 1251, нечувствительная к регистру и нечувствительная к диакритическим знакам. Это покажет вам сопоставления для всех допустимых символов в этом сопоставлении.

Что касается вопроса о поиске, как сказал Кит, я бы рассмотрел вопрос о добавлении полнотекстового индекса в столбец, в котором вы собираетесь искать.

person Codeman    schedule 03.10.2013
comment
Это SQL жалуется, что функция недетерминирована. У меня нет копии точного сообщения (я уже исправил проблему), но оно выдает ошибку. Так что я не могу спорить с тем, что это не детерминировано. Спасибо. - person Frank Monroe; 03.10.2013
comment
Как вы тогда решили проблему? - person Codeman; 04.10.2013

Лучший ответ, который я получил, был от Себастьян Саджарофф. Я использовал его пример, чтобы решить проблему. Он предложил ВИД с УНИКАЛЬНЫМ ИНДЕКСОМ. Это дает хорошее представление о решении:

create table Test(Id int primary key, Name varchar(20))
create view TestCIAI with schemabinding as
select ID, Name collate SQL_Latin1_General_CP1_CI_AI as NameCIAI from Test 
create unique clustered index ix_Unique on TestCIAI (Id)
create unique nonclustered index ix_DistinctNames on TestCIAI (NameCIAI)
insert into Test values (1, 'Sébastien')
--Insertion 2 will fail because of the unique nonclustered indexed on the view 
--(which is case-insensitive, accent-insensitive)
insert into Test values (2, 'Sebastien')
person Frank Monroe    schedule 04.10.2013