将cfloop与queryfilter函数一起使用

时间:2018-11-27 22:38:28

标签: coldfusion coldfusion-2016 qoq

我是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 :(得分:1)

有关应用程序和数据的某些细节遗漏了,因此我做了两个假设。看来您有一个查询对象,要为origCodetoCode过滤和提取费率。在不了解您的数据结构以及您打算如何处理的情况下,我只能提出一些一般性建议。我仍然坚持认为在查询中进行过滤会更好,但是我了解其局限性。由于必须在应用程序内部进行筛选,因此最初返回的大量基础数据以及筛选这些记录的处理都会对性能产生负面影响。

我要做的第一件事是建立一个假查询对象。这是我的第一个假设起作用的地方。我假设您的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 }
    ]
);

在这里我不建议使用“查询查询”,因为对于某些可以很容易实现的事情来说,这是很大的开销。

我创建了一个函数,您可以传入您的origCodetoCode,它将为您返回origRatetoRate的结构。我在代码中包含了一些注释,因此您将能够看到我在做什么。该函数的大部分使用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 ;
}

要分配origRatetoRate,我们首先创建一个ratesStruct返回值来保存费率的结构。过滤查询后,我们仅循环浏览这些过滤结果,并检查行中的code是否与我们的输入变量匹配。我的另一个假设是,数据库将返回不超过两个记录(一个origCode和一个toCode,或者都不返回)。如果可以为code返回多个行,则输出代码将被查询中的最后一个相关行覆盖。如果还有其他适合排序的行,则可以使用它们,并且仅选择所需比率的第一行。我还默认将返回率设为-1,以表示未找到rate的{​​{1}}。如有需要,可以更改。

在那之后,我只是进行了一些测试,以确保我们没有任何疑问。代码位于https://trycf.com/gist/c3b87ca7c508562fd36f3ba6c73829c7/acf2016?theme=monokai

再次,我认为这一切都可以在数据库本身中完成。可能是通过授予您访问存储过程的权限,您可以将codeorigCode传递给该存储过程。

答案 1 :(得分:0)

如果收到有关无效构造的错误,则是因为CF版本不支持==运算符。对于Adobe ColdFusion,直到最近,唯一受支持的equals运算符是eqis或各种比较函数,具体取决于所涉及的变量和意图。

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