Специальный символ в Поиске в PostgreSQL - PullRequest
2 голосов
/ 28 сентября 2011

Я пытаюсь получить имена контактов на основе ключевой строки поиска. Он хорошо работает для английского алфавита и странно ведет себя для специальных символов, таких как _, /, \,%

Мой запрос в функции похож на

SELECT contact_name FROM contacts WHERE LOWER(contact_name) LIKE LOWER('_McDonald%') ORDER BY LOWER(contact_name) ASC LIMIT 1;

Похоже, что во время поиска он получает все имена контактов вместо желаемых. Подобное странное случается для вышеупомянутых специальных символов. Я должен поддержать это. Как мне научить postgres учитывать эти символы? Пожалуйста, ведите меня.

Спасибо и С уважением, Шив.

Ответы [ 3 ]

4 голосов
/ 28 сентября 2011

Я не знаю, какую версию PostgreSQL вы используете, но убедитесь, что вы экранировали любые специальные символы (_,%, \, ...), если вы хотите сопоставить их буквально, как это описано в документы .

Предполагая, что вы хотите найти любые имена контактов, начинающиеся с _McDonald:

SELECT contact_name FROM contacts 
WHERE LOWER(contact_name) LIKE LOWER(E'\\_McDonald%')
ORDER BY LOWER(contact_name) ASC LIMIT 1;
2 голосов
/ 28 сентября 2011

Просто для завершения картинки:

Вы также можете использовать предложение ESCAPE, чтобы указать символ для экранирования подстановочных знаков.Это полезно, если вы хотите включить, например, \ в строку поиска.

SELECT contact_name 
FROM contacts 
WHERE LOWER(contact_name) LIKE LOWER('@_McDonald%') ESCAPE '@'
ORDER BY LOWER(contact_name) ASC 
LIMIT 1;

Кстати: я бы рекомендовал включить опцию конфигурации standard_conforming_strings, чтобыИзбегайте путаницы (ответ Haes позволяет избежать этой проблемы, используя синтаксис E').Начиная с 9.1 это режим по умолчанию в любом случае.

0 голосов
/ 30 ноября 2018

Вы можете использовать префикс E в предложении where перед строкой, используя двойную обратную косую черту, чтобы экранировать следующий символ:

WHERE LOWER(contact_name) LIKE LOWER(E'\\_McDonald%')

ИЛИ Вы можете сделать добавленную оговорку Escape, как показано ниже:

WHERE LOWER(contact_name) LIKE LOWER('@_McDonald%') ESCAPE '@'

Обратите внимание, что первый метод будет работать с предложениями LIKE, SIMILAR TO и NOT SIMILAR TO, но вышеописанный метод будет работать также с более мощными регулярными выражениями POSIX, такими как ~, ~ , ! ~,! ~

В документах вы также можете увидеть некоторые функции, которые могут быть полезны, такие как regexp_replace, где вы можете попробовать это, чтобы экранировать специальные символы в поле contact_name:

SELECT 
regexp_replace(contact_name, '([!$()*+.:<=>?[\\\]^{|}-])', '\\\1', 'g') 
FROM 
contacts 
WHERE
LOWER(contact_name) LIKE LOWER('_McDonald%') 
ORDER BY 
LOWER(contact_name) ASC LIMIT 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...