Как я могу очистить этот запрос SELECT? - PullRequest
2 голосов
/ 25 февраля 2009

Я использую PHP 5 и MySQL 5 на выделенном сервере (Ubuntu Server 8.10) с полным доступом к корневому каталогу. Я очищаю некоторый код LAMP, который я унаследовал, и у меня есть большое количество SQL-запросов с этим типом конструкции:

SELECT ... FROM table WHERE
  LCASE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
    strSomeField, ' ', '-'), ',', ''), '/', '-'), '&', ''), '+', '')
  ) = $somevalue

Игнорирование того факта, что база данных никогда не должна была быть построена так, чтобы сначала требовать такого выбора, а поле $ somevalue необходимо будет параметризовать, чтобы закрыть дыру в безопасности, что является моим лучшим вариантом для исправления WHERE состояние во что-то менее оскорбительное? Если бы я использовал MSSQL или Oracle, я бы просто собрал пользовательскую функцию, но мой опыт работы с MySQL более ограничен, и я раньше не создавал UDF с ним, хотя я доволен кодированием C.

Обновление: Для всех тех, кто уже поднял брови на это в исходном коде, $ somevalue на самом деле что-то вроде $ GET ['product'] & mdash; есть несколько вариантов тема. В этом случае select извлекает продукт из базы данных по имени продукта - после удаления символов, чтобы он соответствовал тому, что можно было ранее передать в качестве параметра URI.

Ответы [ 5 ]

3 голосов
/ 25 февраля 2009

Каков мой лучший вариант для преобразования условия WHERE в нечто менее оскорбительное?

Выполните замену на прикладном уровне, вызов этой логики в базе данных отсутствует. Сделайте это простой старой функцией PHP.

ETA: аааа, я понимаю, что вы имеете в виду. Тогда вы напичканы, все, что осталось, это «тот факт, что база данных никогда не должна была создаваться, чтобы требовать такого выбора в первую очередь»! :-) Вы могли бы переместить REPLACE в сохраненное производство ( CREATE FUNCTION ) ... что, безусловно, сделало бы запрос более приятным, но это как бы подметает проблему под Действительно, так как для выполнения запроса SELECT все еще требуется отсканировать и обработать всю таблицу. Я не думаю, что вы можете сделать намного лучше без изменения схемы, извините.

(я предполагаю, что это функция для получения «очищенного» токена в стиле ID из заголовка текста? Обычно вы действительно делаете это в простой старой функции PHP и сохраняете ее как отдельный столбец из «Настоящий» заголовок. Затем вы можете легко выбрать его и проиндексировать для повышения производительности.)

2 голосов
/ 25 февраля 2009

Проверьте библиотеку регулярных выражений:

В частности:

REGEXP_REPLACE?(text, pattern, replace ...)
1 голос
/ 25 февраля 2009

О боже, это весело. Вот краткое описание того, что он делает с strSomeField:

  • пробелы и косые черты становятся дефисами
  • удалены запятые, амперсанды и знаки плюс
  • преобразовано в нижний регистр

Это не может быть легко сделано в MySQL без добавления пользовательской функции regexp_replace, с которой связан MarkusQ, которая, я думаю, потребует перекомпиляции MySQL.

У вас есть возможность просто обработать все данные в таблице, чтобы в этом не было необходимости? Создайте сценарий PHP, чтобы выбрать все значения в strSomeField, выполнить ту же обработку, что я описал выше, и обновить строки новыми значениями. Или это сломает другие части приложения?

0 голосов
/ 31 мая 2010

после удаления символов, так что соответствует тому, что могло быть ранее передается как параметр URI.

О. Та же ловушка снова и снова.

Не используйте название продукта в качестве ключа!

Тебе не кажется, что ТАК авторы менее опытны, чем ты?
Но посмотрите на URL-адрес ТАКОГО вопроса:
stackoverflow.com/questions/587422/how-can-i-clean-up-this-select-query
Они используют цифровую клавишу, а остальные просто для украшения.
Таким образом, имя может быть отредактировано в любое время, но страница останется прежней. И конечно, никаких проблем, как у вас.

Это не проблема базы данных. Это проблема дизайна. Ошибка, я бы сказал.

0 голосов
/ 26 февраля 2009

Если вы создаете новое поле с предварительно обработанным столбцом strSomeField, вы должны добавить триггер, который автоматически обновляет его при изменении strSomeField. Может устранить некоторые головные боли.

...