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