将 cfloop 与 queryfilter 函数一起使用

Using cfloop with queryfilter function

我是 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>

通过注释掉上面的第一段代码插入第二段代码后,它没有加载页面。如果有人有想法,我真的很感激。提前致谢!

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

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

关于应用程序和数据缺少一些细节,所以我做了几个假设。您似乎有一个查询对象,您想要过滤并从中提取 origCodetoCode 的比率。在不了解您的数据结构以及您打算用它做什么的情况下,我只能提出一些一般性建议。我仍然认为在查询中进行过滤会好得多,但我理解这种局限性。由于您必须在应用程序内部进行过滤,因此您最初 return 的大量基础数据和过滤这些记录的处理都会对性能产生负面影响。

我做的第一件事是设置一个假的查询对象。这是我的第一个假设发挥作用的地方。我假设您的 code 不会在您的 table 中重复,并且该代码将有一个与之相关联的 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,它会 return 你 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 return 值来保存比率结构。在我们过滤查询之后,我们只是遍历那些过滤的结果并检查行中的 code 是否与我们的输入变量匹配。我的另一个假设是数据库将 return 不超过两条记录(一条 origCode 和一条 toCode,或者两者都不)。如果对于 code 可以 return 多行,则输出代码将被查询中最后相关的行覆盖。如果还有其他适合排序的行,则可以使用它们,并且仅 select 所需比率的顶行。我还将 returned 率默认设置为 -1,表示未找到 coderate。如果需要,可以更改。

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

再一次,我认为这一切都可以在数据库本身内完成。可能是通过让您访问可以将 origCodetoCode 传递给的存储过程。