В документации к оператору 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 Studio.
LIKE
он чувствителен к регистру, если нет, тоLIKE
нет