2

В моем ColdFusion 11 приложения с SQL Server 2008 R2-я следующий cfquery тег внутри CF компонента:ColdFusion апостроф проблема с SQL Query

<cfquery name="result_set" dataSource="#request.dsn_name#"> 
    select name, state from myTable #REReplace(where_clause,"''","'","ALL")#   
</cfquery> 

Здесь where_clause переменная. CF заменяет одну единственную цитату двумя, и поэтому я использую функцию REReplace для замены двух одиночных кавычек на один. Поэтому мой запрос изменяется, например. от

select name, state from myTable WHERE name IN (''ABC'') 

к этому:

select name, state from myTable WHERE name IN ('ABC') 

Проблема состоит в том, когда значение столбца имя содержит апостроф, а также. Например.

select name, state from myTable WHERE name IN ('Smith's bat') 

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

UPDATE

Это приложение было разработано лет назад кто-то с помощью ColdFusion MX 7. Первоначально автор создает динамическую строку для where_clause переменной, основанной на определенных условиях. Это длинный файл cfs с несколькими условиями, используемыми для создания динамической строки для where_clause. Следовательно, использование cfqueryparam может быть либо не подходящим, либо может потребовать полного пересмотра кода, который клиент не разрешит.

+5

Гораздо лучший подход - переписать запрос для использования параметров (''). Выполнение этого так, как вы это делаете, крайне подвержено ошибкам и, вероятно, приведет к уязвимости [** SQL injection **] (https://www.owasp.org/index.php/SQL_Injection). –

+5

... и именно поэтому у вас возникла проблема с запросом. Не используйте такой динамический sql. Вместо этого создайте sql внутри cfquery и используйте cfqueryparam для всех параметров (или посмотрите на использование запросов cfscript, которые предлагают немного большую гибкость с параметризованным sql). Это защитит базу данных и устранит этот тип ошибок. – Leigh

+4

Если вы хотите сохранить свою строку SQL за пределами вызова '', вместо этого используйте' queryExecute() ', что позволит вам помещать держатели параметров в строку SQL; а затем передать значения параметров в отдельный массив/struct. Просто * не * жестко закодируйте значения в строку SQL. Это ужасно, неудобно и опасно. –

ответ

1

Это неприятная проблема. Боюсь, я могу только придумать неприятное «решение».

  • подставлено значение разделителей: <cfset where_clause = replace(where_clause, "''", "§§", "ALL")>
  • Затем избежать фактические одиночные кавычки: <cfset where_clause = replace(where_clause, "'", "\'", "ALL")>
  • Теперь вернуться к замене и нормализуют разделители: <cfset where_clause = replace(where_clause, "§§", "'", "ALL")>

Бросив вместе:

<cfset substitution = "§§"> <!--- use whatever char sequence works best for your data ---> 

<!--- fallback in case the substitution is part of your data ---> 
<cfif where_clause contains substitution> 

    <cfset substitution = "°°°"> 
    <!--- 
     you can basically start looping through a bunch of alternatives 
     or even expand the substition with an additional character 
     ...you get the idea 
    ---> 

</cfif> 

<cfset where_clause = replace(where_clause, "''", substitution, "ALL")> 
<cfset where_clause = replace(where_clause, "'", "\'", "ALL")> 
<cfset where_clause = replace(where_clause, substitution, "'", "ALL")> 

<cfquery... 

Как вы можете видеть, это все еще очень проблематично и может однажды потерпеть неудачу. Но, вероятно, нет лучшей альтернативы, если вам нужно иметь дело с переменной where_clause.

0

Вы должны использовать функцию PreserveSingleQuotes, что путь:

<cfquery name="result_set" dataSource="#request.dsn_name#"> 
    select name, state from myTable #PreserveSingleQuotes(REReplace(where_clause,"''","'","ALL"))#   
</cfquery> 

Иметь хороший день!

+0

@PauloTexeira. Ваше предложение дает ошибку: 'Комплексные конструкции не поддерживаются функцией PreserveSingleQuotes' – nam

+0

Распечатайте cfdump своей строки, чтобы помочь нам понять данные. –

+0

Имейте в виду, что это работает только в том случае, если одиночные кавычки правильно экранированы, а какие нет (судя по OP). Говоря из личного опыта, этот динамический sql чрезвычайно подвержен ошибкам и королевской боли для отладки ... Не говоря уже о том, что база данных широко распадается на SQL-инъекцию. Хотя это можно сделать, переключение на «параметризованные» запросы - это более безопасный и безопасный вариант IMO – Leigh