У документації про оператора LIKE нічого не сказано про чутливість до регістру. Є це? Як його ввімкнути / вимкнути?
Я запитую varchar(n)
стовпці щодо інсталяції Microsoft SQL Server 2005, якщо це має значення.
У документації про оператора LIKE нічого не сказано про чутливість до регістру. Є це? Як його ввімкнути / вимкнути?
Я запитую varchar(n)
стовпці щодо інсталяції Microsoft SQL Server 2005, якщо це має значення.
Відповіді:
Не оператор чутливий до регістру, це сам стовпець.
Коли виконується інсталяція SQL Server, для екземпляра вибирається порівняння за замовчуванням. Якщо явно не зазначено інше (перевірте умову зіставлення нижче), коли створюється нова база даних, вона успадковує сортування від екземпляра, а коли створюється новий стовпець, вона успадковує сортування від бази даних, якій вона належить.
Подібне порівняння sql_latin1_general_cp1_ci_as
диктує, як слід обробляти вміст стовпця. CI означає нечутливий регістр, а AS означає чутливий до наголосу.
Повний список порівнянь доступний за адресою https://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx
(а) Щоб перевірити порівняння екземплярів
select serverproperty('collation')
(b) Перевірити порівняння бази даних
select databasepropertyex('databasename', 'collation') sqlcollation
(c) Створити базу даних, використовуючи інший порядок порівняння
create database exampledatabase
collate sql_latin1_general_cp1_cs_as
(d) Створити стовпець із використанням іншого сортування
create table exampletable (
examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
)
(e) Змінити сортування стовпців
alter table exampletable
alter column examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
Можна змінити екземпляр та порівняння бази даних, але це не впливає на раніше створені об'єкти.
Також можна на льоту змінити сортування колон для порівняння рядків, але це дуже не рекомендується у виробничому середовищі, оскільки це надзвичайно дорого.
select
column1 collate sql_latin1_general_cp1_ci_as as column1
from table1
[A-Z]
завжди, не враховує регістр. [ABCDEFGHIJKLMNOPQRSŠTUVWXYZŽÅÄÖ]
однак, схоже, підкоряється сортуванню.
select COLLATION_NAME, iif(cast(COLLATIONPROPERTY(COLLATION_NAME, 'ComparisonStyle') as int) & 1 = 0, 'case sensitive', 'case insensitive') from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'exampletable' and COLUMN_NAME = 'examplecolumn'
Усі ці розмови про співставлення здаються дещо надскладними. Чому б просто не використати щось на зразок:
IF UPPER(@@VERSION) NOT LIKE '%AZURE%'
Тоді ваша перевірка не враховує регістр, незалежно від порівняння
like 'a%'
можна було використовувати індекс, а upper
версія не могла.
like
оператор чутливий до регістру чи ні .
Latin1_General_CI_AS
, тоді це робить UPPER(@@VALUE) NOT LIKE '%SOMETHING%'
або @@COLUMN NOT LIKE '%SOMETHING%'
не має значення: результат буде однаковим.
Ви можете визначити порядок сортування під час визначення таблиці. Якщо ви визначите замовлення з урахуванням регістру, ваш LIKE
оператор поводитиметься з урахуванням регістру; якщо ви визначите порядок зіставлення без урахування регістру, LIKE
оператор також проігнорує регістр символів:
CREATE TABLE Test (
CI_Str VARCHAR(15) COLLATE Latin1_General_CI_AS -- Case-insensitive
, CS_Str VARCHAR(15) COLLATE Latin1_General_CS_AS -- Case-sensitive
);
Ось коротка демонстрація на sqlfiddle, яка показує результати порядку сортування для пошуку за допомогою LIKE
.
Якщо ви хочете здійснити пошук з урахуванням регістру, не змінюючи сортування стовпця / бази даних / сервера, ви завжди можете використати COLLATE
речення, наприклад
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CS_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 1 row
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CI_AS LIKE 'j%';
-- 2 rows
GO
DROP TABLE dbo.foo;
Працює і в інший спосіб, якщо ваш стовпець / база даних / сервер чутливі до регістру, і ви не хочете шукати регістр, наприклад
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CI_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 2 rows
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CS_AS LIKE 'j%';
-- 1 row
GO
DROP TABLE dbo.foo;
WHERE bar COLLATE Latin1_General_CS_AS LIKE '[j-k]%'
його, він повернеться, John
оскільки в цьому порівнянні капітал J
знаходиться між малими j
та малими літерами k
. Це схоже на те, aAbBcC...jJkKlLmM...
що не очевидно. ЗдаєтьсяLatin1_General_BIN
це є більш передбачуваним при пошуку діапазону з оператором LIKE.
like
Оператор приймає два рядки. Ці рядки повинні мати сумісні сортування, що пояснюється тут .
На мій погляд, тоді все ускладнюється. Наступний запит повертає помилку про те, що збіги несумісні:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' COLLATE SQL_Latin1_General_CP1_CI_AS like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
На довільній машині тут типовим сортуванням є SQL_Latin1_General_CP1_CI_AS
. Наступний запит успішний, але не повертає рядків:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
Значення "abc" та "ABC" не співпадають у світі, що враховує регістр.
Іншими словами, існує різниця між відсутністю сортування та використанням сортування за замовчуванням. Коли одна сторона не має сортування, тоді їй "присвоюється" явне сортування з іншої сторони.
(Результати однакові, коли явне порівняння знаходиться зліва.)
Спробуй бігти,
SELECT SERVERPROPERTY('COLLATION')
Тоді з’ясуйте, чи є у вас порівняння з урахуванням регістру чи ні.
Ви можете легко змінити порядок порівняння в студії Microsoft SQL Server Management.
LIKE
чутливий до регістру, якщо це не так, тоLIKE
немає