Как я могу построить 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 можно найти здесь.
Обычно сравнения строк нечувствительны к регистру. Если ваша база данных настроена на сортировку с учетом регистра, вам необходимо принудительно использовать регистр, нечувствительный к регистру:
SELECT balance FROM people WHERE email = '[email protected]'
COLLATE SQL_Latin1_General_CP1_CI_AS
Я нашел другое решение в другом месте; то есть использовать
upper(@yourString)
но все здесь говорят, что в SQL Server это не имеет значения, потому что это игнорирует случай? Я уверен, что наша база данных чувствительна к регистру.
Нет, только использование LIKE
не будет работать. LIKE
выполняет поиск значений, соответствующих точно данному шаблону. В этом случае LIKE
найдет только текст 'sOmeVal', а не 'someval'.
Решающее решение использует функцию LCASE()
. LCASE('sOmeVal')
получает строчную строку вашего текста: "someval". Если вы используете эту функцию для обеих сторон вашего сравнения, она работает:
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
Оператор сравнивает две строчные строки, так что ваш 'sOmeVal' будет соответствовать любой другой нотации 'someval' (например, "Someval", "sOMEVAl" и т.д.).
Вы можете принудительно настроить чувствительность к регистру, выбрав в качестве varbinary:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
Лучшие 2 ответа (от Адама Робинсона и Андрея Каиниковых) довольно правильные, поскольку они технически работают, но их объяснения неверны и во многих случаях могут вводить в заблуждение. Например, хотя сортировка SQL_Latin1_General_CP1_CI_AS
будет работать во многих случаях, ее не следует рассматривать как подходящую сортировку без SQL_Latin1_General_CP1_CI_AS
регистра. Фактически, учитывая, что OP работает в базе данных с сортировкой с учетом регистра (или, возможно, двоичным кодом), мы знаем, что OP не использует сортировку, которая используется по умолчанию для столь многих установок (особенно любой, установленной в ОС). используя американский английский в качестве языка): SQL_Latin1_General_CP1_CI_AS
. Конечно, OP может использовать SQL_Latin1_General_CP1_CS_AS
, но при работе с данными VARCHAR
важно не изменять кодовую страницу, так как это может привести к потере данных, и это контролируется языком/культурой сопоставления (т.е. Latin1_General vs French против иврита и т.д.). Пожалуйста, смотрите пункт № 9 ниже.
Остальные четыре ответа неверны в разной степени.
Я проясню все недоразумения, чтобы читатели могли сделать наиболее подходящий/эффективный выбор.
Не используйте UPPER()
. Это совершенно ненужная дополнительная работа. Используйте предложение COLLATE
. Сравнение строк необходимо выполнить в любом случае, но использование UPPER()
также должно проверять, символ за символом, чтобы увидеть, есть ли отображение в верхнем регистре, а затем изменить его. И вам нужно сделать это с обеих сторон. Добавление COLLATE
просто направляет обработку для генерации ключей сортировки с использованием набора правил, отличного от того, который использовался по умолчанию. Использование COLLATE
определенно более эффективно (или "производительно", если вам нравится это слово :), чем использование UPPER()
, как доказано в этом тестовом скрипте (в PasteBin).
Существует также проблема, отмеченная @Ceisc в ответе @Danny:
В некоторых языках конверсии делаются не туда и обратно. то есть НИЖНЯЯ (х)! = НИЖНЯЯ (ВЕРХНЯЯ (х)).
Турецкий верхний регистр "İ" является распространенным примером.
Нет, сортировка не является настройкой всей базы данных, по крайней мере, не в этом контексте. Существует сопоставление по умолчанию на уровне базы данных, и оно используется в качестве значения по умолчанию для измененных и вновь создаваемых столбцов, в которых не указано предложение COLLATE
(что, вероятно, связано с этим распространенным заблуждением), но оно не влияет на запросы напрямую, если только вы сравниваете строковые литералы и переменные с другими строковыми литералами и переменными или ссылаетесь на метаданные уровня базы данных.
Нет, сопоставление не по запросу.
Сопоставления производятся по предикату (то есть что-то операнду) или выражению, а не по запросу. И это верно для всего запроса, а не только для WHERE
. Это включает в себя СОЕДИНЕНИЯ, ГРУППЫ 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[_]%';
Для получения дополнительной информации о параметрах сортировки, кодировки, и т.д., пожалуйста, посетите: Collations информацию
В какой базе данных вы работаете? С MS SQL Server это параметр базы данных, или вы можете перегрузить его для каждого запроса с помощью ключевого слова COLLATE.