ColdFusion добавляет дополнительные кавычки при построении запросов к базе данных в строках - PullRequest
11 голосов
/ 05 ноября 2008

Я пишу код в ColdFusion, но пытаюсь остаться в cfscript, поэтому у меня есть функция, которая позволяет мне передать запрос для его запуска с <cfquery blah > #query# </cfquery>

Почему-то, когда я строю свои запросы с помощью sql = "SELECT * FROM a WHERE b='#c#'" и передаю их, ColdFusion заменил одинарные кавычки на 2 одинарные. так что в последнем запросе оно становится WHERE b=''c''.

Я пытался создавать строки множеством разных способов, но я не могу оставить только одну цитату. Даже замена строки не имеет никакого эффекта.

Есть идеи, почему это происходит? Это разрушает мои надежды жить в cfscript на время этого проекта

Ответы [ 4 ]

18 голосов
/ 06 ноября 2008

ColdFusion по своей конструкции экранирует одинарные кавычки при интерполяции переменных внутри тегов <cfquery>.

Чтобы делать то, что вы хотите, вам нужно использовать функцию PreserveSingleQuotes().

<cfquery ...>#PreserveSingleQuotes(query)#</cfquery>

Это, однако, не устраняет опасность внедрения SQL-кода, которому вы подвергаетесь.

Использование <cfqueryparam> также позволяет вашей базе данных кэшировать запрос, что в большинстве случаев повышает производительность.

Может быть полезно прочитать старую колонку Бена Форты и недавнюю статью Брэда Вуда для получения дополнительной информации о преимуществах использования <cfqueryparam>.

6 голосов
/ 06 ноября 2008

Ответ на ваш вопрос, как говорили другие, использует preserveSingleQuotes(...)

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

Поместите ваш SQL в теги cfquery с любыми подходящими if / / и т.д. и убедитесь, что все CF переменные используют тег cfqueryparam.

(Обратите внимание: если вы используете переменные в предложении ORDER BY, вам нужно вручную экранировать любые переменные; cfqueryparam нельзя использовать в предложениях ORDER BY)

4 голосов
/ 06 ноября 2008

ColdFusion автоматически экранирует одинарные кавычки в тегах <cfquery> при использовании следующего синтаксиса:

SELECT * FROM TABLE WHERE Foo='#Foo#'

Если вы хотите сохранить одинарные кавычки в #Foo#, вы должны позвонить #PreserveSingleQuotes(Foo)#.

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

SELECT * FROM TABLE WHERE Foo='#LCase(Foo)#' /* Single quotes are retained! */

В этом свете функция PreserveSingleQuotes() (см. Adobe LiveDocs ) - это не что иное, как «нулевая операция» со значением - превращение его в результат функции для обхода автоматического экранирования. 1015 *

0 голосов
/ 05 января 2009

Я проголосовал за ответ Дейва, так как думал, что он хорошо поработал.

Я хотел бы добавить, что есть также несколько различных инструментов, разработанных для ColdFusion, которые могут упростить многие типичные задачи SQL, которые вы, вероятно, будете выполнять. Есть очень легкий инструмент под названием DataMgr , написанный Стивом Брайантом, а также Transfer от Марка Манделя, Reactor , который был первоначально создан Дугом Хьюзом и одним из них. Я разработал под названием DataFaucet . У каждого из них есть свои сильные и слабые стороны. Лично я думаю, что вы склонны считать DataFaucet тем, кто даст вам наилучшую возможность оставаться в cfscript, с различными синтаксисами для построения различных типов запросов.

Вот несколько примеров:

qry = datasource.select_avg_price_as_avgprice_from_products(); //(requires CF8)

qry = datasource.select("avg(price) as avgprice","products"); 

qry = datasource.getSelect("avg(price) as  avgprice","products").filter("categoryid",url.categoryid).execute();

qry = datasource.getSelect(table="products",orderby="productname").filter("categoryid",url.categoryid).execute();


Инфраструктура гарантирует, что cfqueryparam всегда используется с этими операторами фильтра для предотвращения атак с использованием SQL-инъекций, и существует аналогичный синтаксис для операторов вставки, обновления и удаления. (Есть пара простых правил, чтобы избежать sql-инъекций .)

...