2017-01-10 8 views
0
<cfif structKeyExists(url, 'results')> 
    <cfquery datasource="UIAAWeb" name="fullQuery"> 
     SELECT * 
     FROM BusinessDirectory 
     ORDER BY businessname 
    </cfquery> 
<cfelse> 
    <cfquery datasource="UIAAWeb" name="BusinessQuery"> 
     SELECT * 
     FROM BusinessDirectory 
     WHERE 
     <!--- Matches Exact Last Name if Match Radio is selected ---> 
     <cfif #form.match# is "yes"> 
      businessname = '#form.keyword#' 
     </cfif> 
     <!--- Matches Last Names Starting with user inputted letter ---> 
     <cfif (#match# is "no") AND (#form.keyword# neq "")> 
      businessname LIKE '#form.keyword#%' 
     </cfif> 
     <!--- Gets all award types from selected field of awards ---> 
     <cfif #form.industry# neq "*"> 
      AND industry IN ('#form.industry#') 
     </cfif> 

     <!--- Matches Exact Last Name if Match Radio is selected ---> 
     <cfif #form.match1# is "yes"> 
      AND city = '#form.city#' 
     </cfif> 
     <!--- Matches Last Names Starting with user inputted letter ---> 
     <cfif (#match1# is "no") AND (#form.city# neq " ")> 
      AND city LIKE '#form.city#%' 
     </cfif> 

     <!--- Gets all award types from selected field of awards ---> 
     <cfif #form.state# neq "*"> 
      state IN ('#form.state#') 
     </cfif> 

     <!--- Gets all award types from selected field of awards ---> 
     <cfif #form.country# neq "*"> 
      country IN ('#form.country#') 
     </cfif> 

    ORDER BY #sort# 
</cfquery> 

Я пытаюсь написать поисковый запрос, как это так, однако, когда я держу выполнение страницы поиска я получаю внутреннюю ошибку 500 сервера:CFQuery Предоставление Одда внутреннего серверу 500 Ошибки

Element CITY is undefined in FORM. The specific sequence of files included or processed is: C:\inetpub\wwwroot\business\search\search_results.cfm, line: 139

Если удалить city из всех областей запроса я получаю эту ошибку:

Error Executing Database Query.Incorrect syntax near the keyword 'AND'. The specific sequence of files included or processed is: C:\inetpub\wwwroot\business\search\search_results.cfm, line: 146

И если я удалю AND отовсюду я получаю эту ошибку

Error Executing Database Query.Incorrect syntax near the keyword 'industry'. The specific sequence of files included or processed is: C:\inetpub\wwwroot\business\search\search_results.cfm, line: 146

Что я делаю неправильно/как это исправить? Я проверил и перепроверял мою форму, и все правильно определено.

searchform

Так что я пытаюсь заставить его искать через все из них, но игнорировать поле, если один будет пропущен? Кажется, я не могу его оставить, если поле опущено.

Спасибо!

+0

Пара советов 1. RE: * Элемент CITY не определен * Радио кнопки существуют только в том случае, если они проверяются. Либо убедитесь, что он существует сначала ИЛИ определите значение по умолчанию с 'cfparam' 2. ** Никогда ** используйте необработанные клиентские значения в запросе. Всегда используйте 'cfqueryparam' 3. Нет необходимости в знаках фунта в операциях' cfif'. 4. Строки «Да/Нет» будут оцениваться как логические, то есть «true/false». Итак, предполагая, что поле определено, вместо записи '' just use '' – Leigh

ответ

3

Похож на проблему при динамическом генерировании предложения SQL WHERE.

Похоже, у вас есть ключевое слово WHERE. Если на нет условия, то в текст SQL не будет включена часть businessname = 'val'. Таким образом, сгенерированный SQL будет недействительным.

Если нет условия на businessname, но есть один на industry, код будет генерировать недопустимый SQL конструкцию, например:

WHERE AND industry = 'someval' 
     ^^^ 

(В этой конструкции, маркер AND неожиданна ключевое слово MySQL не ожидает этого.)

Если мы исправим код, чтобы удалить ключевое слово AND, чтобы исправить эту проблему, мы создаем еще одну проблему. Когда, когда он выполняет и есть условие на businessname, код будет генерировать недопустимый SQL конструкцию, которая выглядит следующим образом (потому что мы удалили AND ключевое слово):

WHERE businessname = 'val' industry = 'someval' 
          ^^^^^^^^ 

(В этой конструкции, когда MySQL сталкивается industry, . он ожидает найти маркер ключевого слова, такие как AND



чтобы решить эту проблему, я рекомендую шаблон кода, как это:

Начните с текста запроса, заканчивающегося " WHERE 1=1".

Это не влияет на запрос, так как условие всегда будет оцениваться как ИСТИНА. (Оптимизатор просто выбросит его.) Мы включаем только это, чтобы упростить остальную часть нашего кода.

Позже в коде, когда нам нужно добавить предикат (условие) на п WHERE, мы просто используем AND ключевое слово. (И мы помним, чтобы включить требуемый пробел перед ключевым словом)) Мы присоединять:.

" AND somecol = 'somevalue'" 

И мы следуем за тот же шаблон для каждого условия поиска мы, возможно, потребуется добавить к статье WHERE.

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

Если мы добавим предикаты (условия поиска), наш код не должен беспокоиться о том, что ключевое слово WHERE уже включено в инструкцию или нет. При добавлении первого предиката необходимо использовать ключевое слово WHERE вместо AND. И нам нужно будет следить за этим. Для первого условия, которое мы добавляем, потребуется ключевое слово WHERE, для последующих условий потребуется AND.

Поскольку существует несколько условных проверок того, будет ли предикат добавлен в инструкцию, нам нужно будет проверять каждый раз, когда мы хотим добавить в оператор. Нам нужно спросить: «Разве мы уже начали предложение WHERE?», Или «это первое условие в предложении WHERE

Имея в своем составе WHERE 1=1, мы делаем работу немного проще. Нам не нужно отслеживать, добавили ли мы еще ключевое слово WHERE.

Конец результата шаблона, мы получаем немного более утонченную инструкцию SQL (с тривиальным условием 1=1). Но обратная сторона заключается в том, что мы получаем немного более простой код.


После этой модели, мы ожидаем, что наш код генерирует операторы SQL, как это:

без каких-либо условий поиска, добавленных к заявлению:

WHERE 1=1 

, который действителен.

С условием поиска на city ...

WHERE 1=1 AND city = 'somevalue' 

снова, это справедливо.

С условием поиска на industry ...

WHERE 1=1 AND industry = 'somevalue' 

С условиями поиска на обоих city и industry

WHERE 1=1 AND city = 'somevalue' AND industry = 'somevalue' 

и так далее.

+0

, поэтому мне нужно несколько операторов where? –

+0

Uhhhhmmmm, no. Я отредактировал ответ, чтобы указать, что я думаю, что происходит с вашим кодом, что не так с SQL, который создается. Исправление для вашего кода - добавить «1 = 1» после ключевого слова «WHERE». А затем добавьте '' AND'' перед 'businessname'. (Я думаю, что могут возникнуть некоторые другие проблемы с кодом, например, генерация списка 'IN'.) Но я предполагаю, что шаблон' WHERE 1 = 1', всегда добавляющий 'AND condition', исправит проблему, составление отчетов. – spencer7593

+1

* могут возникнуть некоторые другие проблемы с кодом, например, генерация списка IN * Yep. Они не будут работать должным образом, если переменные, такие как '# form.state #', содержат несколько значений. – Leigh

1

Вы будете хотеть использовать <cfqueryparam> потому

  1. Ваш код уязвим для SQL Injection
  2. Это может сделать списки значений.

    ... 
    WHERE 1= 1 
    
    <!--- Matches Exact Last Name if Match Radio is selected ---> 
    <cfif form.match is "yes"> 
        AND businessname = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#form.keyword#"> 
    </cfif> 
    <!--- Matches Last Names Starting with user inputted letter ---> 
    <cfif (form.match is "no") AND (form.keyword neq "")> 
        AND businessname LIKE <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#form.keyword#%"> 
    </cfif> 
    <!--- Gets all award types from selected field of awards ---> 
    <cfif form.industry neq "*"> 
        AND industry IN (<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#form.industry#" list="yes">) 
    </cfif> 
    
    ... 
    

Обратите внимание, что последний имеет cfqueryparamlist="yes"

+1

@Jacob Langreck - вам также необходимо защитить предложение ORDER BY # sort # (которое широко открыто для SQL-инъекции). Однако это невозможно сделать с помощью cfqueryparam. – Leigh

+0

Как я могу получить это для поиска по нескольким полям, причем не все поля требуются, если я на правильном пути? Я использую OR вместо этого, но он все еще показывает результаты. –

+0

Это очень открытый вопрос. Часто есть несколько способов программирования чего-то. В качестве стандарта кодирования я стараюсь избегать '' внутри ''. Но нынешний подход будет работать. –

0

Джейкоба, если вы все еще ищете решение для этого, то, как и все предложил попробовать это.

<!--- DUMP FORM VALUES TO SEE WHAT IS BEING RETURNED ---> 
<CFDUMP VAR="#FORM#"> 

<cfif structKeyExists(url, 'results')> 
    <cfquery datasource="UIAAWeb" name="fullQuery"> 
     SELECT * 
     FROM BusinessDirectory 
     ORDER BY businessname 
    </cfquery> 
<cfelse> 
    <cfquery datasource="UIAAWeb" name="BusinessQuery"> 
     SELECT * 
     FROM BusinessDirectory 
     WHERE 
       1 = 1 
     <!--- Matches Exact Last Name if Match Radio is selected ---> 
     <cfif #form.match# is "yes"> 
      AND businessname = '#form.keyword#' 
     </cfif> 
     <!--- Matches Last Names Starting with user inputted letter ---> 
     <cfif (#match# is "no") AND (#form.keyword# neq "")> 
      AND businessname LIKE '#form.keyword#%' 
     </cfif> 
     <!--- Gets all award types from selected field of awards ---> 
     <cfif #form.industry# neq "*"> 
      AND industry IN ('#form.industry#') 
     </cfif> 


    ORDER BY #sort# 
</cfquery> 

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

Кроме того, предложение cfqueryparam было на месте. Не знал, что вы можете сделать список = «да». Это отличный совет. :-)

 Смежные вопросы

  • Нет связанных вопросов^_^