Как искать совпадения с необязательными специальными символами в SQL? - PullRequest
2 голосов
/ 14 мая 2009

У меня проблема с поисковым запросом, который я использую, мои данные содержат имена и информацию, которая имеет апострофы в различных формах (в кодировке HTML и фактическая). Так, например, я хотел бы альтернативу этому:

SELECT * FROM Customers WHERE REPLACE(LastName,'''','') 
LIKE Replace('O''Brien,'''','')

Это всего лишь пример, я хочу, чтобы, если кто-то наберет OBrien или O'Brien, это все еще работало, мне нужно заменить три версии персонажа, и данные будут получены из источника и не могут быть изменены - что можно сделать с запросом, чтобы этот вид поиска работал.
У меня есть Предметы с именами, которые работают таким образом, которые в настоящее время имеют много вложенных функций REPLACE и не могут найти что-то, что будет работать таким образом, что более эффективно.
Я использую MS SQL 2000 с ASP, если это помогает.


Редактировать

Вот запрос, который должен соответствовать O'Brien или OBrien, этот запрос делает это, но он слишком неэффективен - к нему присоединяется другой для Имен элементов и FirstName (необязательно) для сравнения.

SELECT * FROM Customers
WHERE 
REPLACE(REPLACE(REPLACE(LastName,''',''),''',''),'''','') 
LIKE 
REPLACE(REPLACE(REPLACE('%O'Brien%',''',''),''',''),'''','')

Ответы [ 4 ]

1 голос
/ 14 мая 2009

Если вы хотите оставаться верным и делать это в SQL, это, вероятно, лучшее, что вы можете сделать

SELECT * FROM Customers WHERE 
LastName LIKE 'O%Brien' AND 
REPLACE(LastName,'''','') LIKE 'O''Brien'

Из-за плохой избирательности вы все равно иногда будете сканировать таблицы.

Причиной первой попытки является использование существующего индекса. Причина второго совпадения состоит в том, чтобы гарантировать, что фамилии, такие как ObbBrien, не совпадают.

Конечно, лучшее, что можно сделать, это не нуждаться в уродливой замене. Это может быть достигнуто в приложении путем хранения дополнительного чистого столбца фамилии. Или в триггере. Или в индексированном представлении.

1 голос
/ 14 мая 2009

Для чистого SQL экранирование совершенно не нужно.

SELECT * FROM Customers WHERE LastName = 'O''Brien'
1 голос
/ 14 мая 2009

Вы можете попробовать это:

SELECT * 
FROM Customers 
WHERE LastName LIKE Replace('O''Brien,'''','%')

Это должно позволить ему использовать индекс, поскольку вы не изменяете исходный столбец.

0 голосов
/ 14 мая 2009

Используйте параметры вместо построения запросов в коде.

Если вы используете ADO, вы можете использовать следующий синтаксис:

Dim cmd, rs, connect, intNumber
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = "your connectionstring"
cmd.CommandText = "SELECT * FROM Customers WHERE LastName LIKE @LastName"
cmd.Parameters.Append cmd.CreateParameter("@LastName",,,,"O'Brien")
Set rs = cmd.Execute 

Это должно выполнить запрос и вставить строку O'Brien, правильно отформатированную для вашей базы данных.

Использование параметров гарантирует, что все значения правильно отформатированы, а также защищает вас от атак SQL-инъекций.

...