Как создать SQL-запрос (MS SQL Server), в котором в предложении «where» не учитывается регистр?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
Я хочу, чтобы результаты возвращались, игнорируя дело
Как создать SQL-запрос (MS SQL Server), в котором в предложении «where» не учитывается регистр?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
Я хочу, чтобы результаты возвращались, игнорируя дело
В конфигурации базы данных SQL Server по умолчанию сравнение строк выполняется без учета регистра. Если ваша база данных переопределяет этот параметр (за счет использования альтернативного сопоставления), вам необходимо указать, какой тип сопоставления использовать в вашем запросе.
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
Обратите внимание, что сопоставление, которое я предоставил, является просто примером (хотя, скорее всего, оно вам подойдет). Более подробный обзор параметров сортировки SQL Server можно найти здесь.
WHERE
, и это повлияет на все предложения WHERE
, верно?
- person ashleedawg; 03.05.2018
UPPER
или LOWER
, а затем использовать LIKE
для поиска?
- person Shaiju T; 29.08.2018
Обычно сравнение строк не зависит от регистра. Если ваша база данных настроена на сортировку с учетом регистра, вам необходимо принудительно использовать ее без учета регистра:
SELECT balance FROM people WHERE email = '[email protected]'
COLLATE SQL_Latin1_General_CP1_CI_AS
Я нашел другое решение в другом месте; то есть использовать
upper(@yourString)
но все здесь говорят, что в SQL Server это не имеет значения, потому что он все равно игнорирует регистр? Я почти уверен, что наша база данных чувствительна к регистру.
LIKE
) В противном случае я могу порекомендовать также взглянуть на myField LIKE 'someValue'
. Однако для LIKE БД должна быть настроена на нечувствительность к регистру (как и большинство из них).
- person skofgar; 10.02.2014
COLLATE
. Я понятия не имею, почему вы говорите, что добавление COLLATE {collation_name}
к предикату является чрезмерным. Это безосновательное заявление. Идея состоит в том, чтобы использовать нечувствительную к регистру версию сопоставления, которую столбец уже использует, и в этом случае невозможна потеря данных (поскольку нет преобразования кодовой страницы). См. мой ответ для получения пояснений по сравнению строк, особенно в пункте № 1.
- person Solomon Rutzky; 01.02.2019
Лучшие 2 ответа (от Адама Робинсона и Андрей Кайников) вроде как правильны в том смысле, что они технически работают, но их объяснения неверны и поэтому во многих случаях могут вводить в заблуждение. Например, хотя сортировка SQL_Latin1_General_CP1_CI_AS
будет работать во многих случаях, ее не следует считать подходящей сортировкой без учета регистра. На самом деле, учитывая, что OP работает в базе данных с учетом регистра (или, возможно, двоичного) сопоставления, мы знаем, что OP не использует сопоставление, которое используется по умолчанию для многих установок (особенно для тех, которые установлены в ОС). используя американский английский язык): SQL_Latin1_General_CP1_CI_AS
. Конечно, OP может использовать SQL_Latin1_General_CP1_CS_AS
, но при работе с данными VARCHAR
важно не менять кодовую страницу, так как это может привести к потере данных, и это контролируется языком/культурой сопоставление (т.е. Latin1_General против французского против иврита и т.д.). См. пункт № 9 ниже.
Остальные четыре ответа неверны в той или иной степени.
Я разъясню здесь все недоразумения, чтобы читатели, надеюсь, могли сделать наиболее подходящий/эффективный выбор.
#P6##P7#
Нет, сопоставление не является настройкой всей базы данных, по крайней мере, не в этом контексте. Существует сопоставление по умолчанию на уровне базы данных, и оно используется по умолчанию для измененных и вновь созданных столбцов, в которых не указано предложение COLLATE
(вероятно, отсюда и происходит это распространенное заблуждение), но оно не влияет на запросы напрямую, если вы не сравниваете строковые литералы и переменные с другими строковыми литералами и переменными или ссылаетесь на метаданные уровня базы данных.
Нет, сопоставление не для каждого запроса.
Сопоставления выполняются по предикату (т. е. по операнду что-то) или по выражению, а не по запросу. И это верно для всего запроса, а не только для предложения WHERE
. Это касается JOIN, GROUP BY, ORDER BY, PARTITION BY и т. д.
Нет, не конвертируйте в VARBINARY
(например, convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
) по следующим причинам:
_BIN2
, если вы используете SQL Server 2008 или новее, иначе у вас нет другого выбора, кроме как использовать тот, который заканчивается на _BIN
. Если данные NVARCHAR
, то не имеет значения, какую локаль вы используете, поскольку в этом случае они все одинаковы, поэтому Latin1_General_100_BIN2
работает всегда. Если данные VARCHAR
, вы должны использовать ту же локаль, в которой находятся данные в данный момент (например, Latin1_General
, French
, Japanese_XJIS
и т. д.), поскольку локаль определяет используемую кодовую страницу, а изменение кодовых страниц может изменить данные (т. е. потеря).CONVERT()
будет использоваться значение по умолчанию 30. Опасность заключается в том, что если длина строки может превышать 30 байт, она будет автоматически усечена, и вы, скорее всего, получите неверные результаты от этого предиката.Нет, LIKE
не всегда чувствителен к регистру. Он использует сопоставление столбца, на который ссылаются, или сопоставление базы данных, если переменная сравнивается со строковым литералом, или сопоставление, указанное в необязательном предложении COLLATE
.
LCASE
не является функцией SQL Server. Похоже, это Oracle или MySQL. Или, возможно, Visual Basic?
Поскольку контекст вопроса сравнивает столбец со строковым литералом, ни сопоставление экземпляра (часто называемого «сервером»), ни сопоставление базы данных не имеют здесь никакого прямого влияния. Параметры сортировки хранятся для каждого столбца, и каждый столбец может иметь разные параметры сортировки, и эти параметры сортировки не обязательно должны быть такими же, как параметры сортировки по умолчанию в базе данных или параметры сортировки экземпляра. Конечно, параметры сортировки экземпляра используются по умолчанию для вновь созданной базы данных в качестве параметров сортировки по умолчанию, если предложение COLLATE
не было указано при создании базы данных. Точно так же сопоставление базы данных по умолчанию — это то, что будет использовать измененный или вновь созданный столбец, если не указано условие COLLATE
.
Вы должны использовать параметры сортировки без учета регистра, которые в остальном совпадают с параметрами сортировки столбца. Используйте следующий запрос, чтобы найти параметры сортировки столбца (измените имя таблицы и имя схемы):
SELECT col.*
FROM sys.columns col
WHERE col.[object_id] = OBJECT_ID(N'dbo.TableName')
AND col.[collation_name] IS NOT NULL;
Затем просто измените _CS
на _CI
. Таким образом, Latin1_General_100_CS_AS
станет Latin1_General_100_CI_AS
.
Если в столбце используется двоичная сортировка (оканчивающаяся на _BIN
или _BIN2
), найдите аналогичную сортировку, используя следующий запрос:
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
Например, предположив, что столбец использует Japanese_XJIS_100_BIN2
, сделайте следующее:
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
Дополнительную информацию о сопоставлениях, кодировках и т. д. см. на странице Информация о сопоставлениях.
Нет, только с помощью LIKE
не получится. LIKE
ищет значения, точно соответствующие заданному шаблону. В этом случае LIKE
найдет только текст "sOmeVal", а не "someval".
Практическим решением является использование функции LCASE()
. LCASE('sOmeVal')
получает строку вашего текста в нижнем регистре: 'someval'. Если вы используете эту функцию для обеих сторон вашего сравнения, она работает:
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
Оператор сравнивает две строки в нижнем регистре, так что ваш «sOmeVal» будет соответствовать любому другому обозначению «someval» (например, «Someval», «sOMEVAl» и т. д.).
LCASE()
в SQL Server (по крайней мере, я не вижу). Я думаю, что этот ответ для совершенно другой СУБД. См. мой ответ для получения пояснений по сравнению строк.
- person Solomon Rutzky; 01.02.2019
Вы можете принудительно учитывать регистр, приводя к такому varbinary:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
Вы в какой базе? В MS SQL Server это параметр для всей базы данных, или вы можете переопределить его для каждого запроса с помощью ключевого слова COLLATE.