Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Запросы с нулями и списками

Автор вопроса: James A MohlerОтветов: 2

У меня есть

QueryExecute(

    SELECT *
    FROM dbo.pages
    WHERE ID IN ( :id )
    ...
   ,
   {
       id : { value = rc.id, cfsqltype : "cf_sql_integer, list : true }
   }

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

  • Чтобы было ясно... Это то, что вам нужно? stackoverflow.com/questions/19357990/ TRose 29.08.2019
  • (Изменить) Это невозможно только с одним предложением IN. Я считаю, что самый чистый способ - построить оператор sql условно, т.е. добавить это условие к предложению where, только если параметр не пуст. Подход or, упомянутый в ссылке, действительно работает, но для этого потребуется более сложный код + sql, который менее читаем IMO. SOS 29.08.2019
  • @TRose очень похоже, но с IN James A Mohler 29.08.2019
  • Если вы хотите написать это таким образом, это требует двух условий. Первое является текущим предложением IN, а второе должно возвращать true, когда переменная пуста. Например where ( column IN ( :idList ) OR :copyIDList = '' ) ... more . SOS 29.08.2019

cfmlcoldfusion-2016coldfusioncfqueryparam

Ответы

Ответ 1 · рейтинг 3 · Dan Roberts

Здесь есть два разных варианта.

1) Вы можете манипулировать строкой запроса, чтобы включить оператор IN только в том случае, если переменная не пуста.

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

<cfset sqlstr = "SELECT * FROM dbo.pages" />
<cfif len(rc.id)>
    <cfset sqlstr &= " WHERE ID IN ( :id )" />
</cfif>

Вы могли бы создавать более чисто с условным выводом...

WHERE #len(rc.id) ? "ID IN ( :id )" : ""#

Чтобы не беспокоиться о включении WHERE/AND/OR, один небольшой трюк заключается в включении предложения, которое всегда будет проходить (или никогда в случае ORing).

WHERE 1=1
    #len(rc.id) ? "AND ID IN ( :id )" : ""#
    AND ...

2) Дважды передать параметр и выполнить проверку в базе данных

SELECT *
FROM dbo.pages
WHERE (len(':id') = 0 OR ID IN ( :id ))
...

-- note: this may be problematic if CF is passing null when blank

или просто длина

    QueryExecute(

    SELECT *
    FROM dbo.pages
    WHERE (:idlen > 0 OR ID IN ( :id ))
    ...
   ,
   {
       id : { value = rc.id, cfsqltype : "cf_sql_integer, list : true },
       idlen : { value = len(rc.id), cfsqltype : "cf_sql_integer" }
   }

Ответ 2 · Kannan.P

Здесь я также привел пример кода для создания условного параметра queryparam. Для целей тестирования я создал некоторые параметры и значения по умолчанию.

<cfparam name="id" default="1,2,3,4,5,6">

Установите детали запроса в виде строки и сохраните ее в другой переменной, как упомянуто выше @danRoberts.

<cfset MyQry = "SELECT * FROM pages ">

Убедитесь, что значение rc.id пустое. Если это не так, добавьте предложение IN.

<cfif len(rc.id) >
    <cfset MyQry &= " WHERE id IN ( :id ) ">
</cfif>

Для справки, я также добавил несколько дополнительных операторов.

<cfset MyQry &= " limit 10 ">

Затем создайте новый запрос на основе оператора new.

<cfset qry = new Query( datasource ='yourDataSource' , sql = MyQry) >

После этого добавьте queryParam для :ID, если rc.id не пуст.

<cfif len(rc.id) >
<cfset qry.addParam( name="id", value="#rc.id#",cfsqltype="cf_sql_varchar",list='true') >
</cfif>

Примечание. При использовании INoperator вы должны установить list='true' для параметра queryParam.

Затем вы выполняете запрос, как показано ниже

<cfset Result = qry.execute().getResult() >
<cfdump var="#Result#" />

Предложение WHERE с queryParam будет выполняться только тогда, когда rc.ID содержит значение.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы