Использование cfloop с функцией queryfilter - PullRequest
0 голосов
/ 28 ноября 2018

Я новичок в ColdFusion и пытаюсь использовать cfloop для приведенного ниже кода:

<cfscript>
    var origRate = 0;
    var toRate = 0;

    rates = myQuery.filter(function (obj) {
          return (obj.code == arguments.origCode || obj.code == 
    arguments.toCode)
            })
</cfscript>

Я изменил ниже исходный код и вставил приведенный выше новый код, чтобы избежать встроенных SQL-запросов:

<cfquery name="rates" dbtype="query">
        select code, rate
  from myQuery
  where code = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.origCode#" />
     or code = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.toCode#" />
</cfquery>

Я попытался использовать cfloop без изменения предыдущего кода, как показано ниже, но он не работает:

<cfloop query="rates">
    <cfscript>
        if (code == arguments.origCode) origRate = rate;
        if (code == arguments.toCode) toRate = rate;
    </cfscript>
</cfloop>

Как только второй блок кода был вставлен, закомментировав первый блок кода выше, он не загрузил страницу.Если у кого-то есть идея, я действительно ценю это.Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Были некоторые недостающие детали о приложении и данных, поэтому я сделал пару предположений.Похоже, что у вас есть объект запроса, который вы хотите отфильтровать и получить значения для origCode и toCode.Не зная больше о вашей структуре данных и о том, что вы планируете с ней делать, я могу лишь сделать некоторые общие предложения.Я по-прежнему утверждаю, что было бы намного лучше отфильтровать запрос, но я понимаю ограничение.Поскольку вам необходимо выполнять фильтрацию внутри приложения, объем исходных данных, которые вы изначально возвращаете, и обработка для фильтрации этих записей негативно влияют на производительность.

Первым делом я настроил поддельный объект запроса.Это где мое первое предположение вступает в игру.Я предположил, что ваш code не будет дублироваться в вашей таблице, и что с кодом будет ассоциирован rate.

myQuery = queryNew(
    "code, rate",
    "integer, integer",
    [
      { "code" : 1 , "rate" : 10 } , 
      { "code" : 2 , "rate" : 15 } , 
      { "code" : 3 , "rate" : 20 } , 
      { "code" : 4 , "rate" : 25 } , 
      { "code" : 5 , "rate" : 30 }
    ]
);

Я бы не рекомендовал Query of Query здесь, потому что это требует много времени для чего-то, что может быть выполнено довольно легко.

Я создал функцию, которую вы можете передать в свои origCode и toCode, и она вернет вам структуру origRate и toRate.Я включил некоторые комментарии в код, чтобы вы могли увидеть, что я делал.Основная часть функции использует закрытие filter() для фильтрации записей запросов.Если вы сможете фильтровать через SQL, вы сможете устранить этот блок.

function returnNewRates( required Numeric origCode, required Numeric toCode ) {
    local.ratesStruct = { "origRate":-1, "toRate":-1 } ;

    // This will be our query. If we _have_ to use an existing query, pass it in and duplicate() it. (Pass by Reference!)
    local.qry = duplicate( myQuery )  ; 
    /////////////
    // Closure to filter the query. This should be done in SQL.
    // https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-m-r/queryfilter.html
    local.filteredQuery = qry
        .filter( function (obj) {
                return ( obj.code == origCode || obj.code == toCode ) ;
        } ) ;

    // Now assign new rates. NOTE: The query shouldn't return more than 2 rows. We can validate if needed.
    for ( var r IN filteredQuery ) {
        if( r.code == arguments.origCode ) { ratesStruct.origRate = r.rate ; }
        if( r.code == arguments.toCode ) { ratesStruct.toRate = r.rate ; }
    }

    return ratesStruct ;
}

Чтобы назначить origRate и toRate, мы сначала создаем возвращаемое значение ratesStruct для хранения структуры ставок.После того как мы отфильтруем наш запрос, мы просто пройдемся по этим отфильтрованным результатам и проверим, совпадает ли code в строке с нашими входными переменными.Еще одно из моих предположений заключалось в том, что база данных будет возвращать не более двух записей (одна origCode и одна toCode или ни одна).Если для code можно вернуть более одной строки, то выходные коды будут перезаписаны последней связанной строкой в ​​запросе.Если есть другие строки, подходящие для сортировки, то их можно использовать и выбрать только верхнюю строку для необходимой скорости.Я также по умолчанию возвратил ставки в -1, чтобы показать, что code не было найдено для *1028*.Это может быть изменено, если необходимо.

После этого я просто провел несколько тестов, чтобы убедиться, что мы не получили никакого выигрыша.Код на https://trycf.com/gist/c3b87ca7c508562fd36f3ba6c73829c7/acf2016?theme=monokai.

И снова, я думаю, что все это, вероятно, может быть сделано в самой базе данных.Возможно, предоставляя вам доступ к хранимой процедуре, которую вы можете передать origCode и toCode.

0 голосов
/ 28 ноября 2018

Если вы получаете ошибку о недопустимой конструкции, это связано с тем, что версия CF не поддерживает оператор ==.Для Adobe ColdFusion до недавнего времени единственными поддерживаемыми операторами равенства были eq, is или различные функции сравнения в зависимости от задействованных переменных и намерений.

<cfloop query="rates">
    <cfscript>
        if (code eq arguments.origCode) origRate = rate;
        if (code eq arguments.toCode) toRate = rate;
    </cfscript>
</cfloop>
...