1

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

一旦通过注释掉上面的第一块代码插入第二块代码,它就不会加载页面。如果有人有想法,我真的很感激。先感谢您!

4

2 回答 2

1

有一些关于应用程序和数据的细节缺失,所以我做了几个假设。看来您有一个查询对象,您想从中筛选和提取origCodea 和 a 的费率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,因为对于可以相当容易地完成的事情来说,它的开销很大。

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

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

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

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

于 2018-11-29T00:42:09.943 回答
0

如果您收到有关无效构造的错误,那是因为 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>
于 2018-11-28T14:32:05.753 回答