如何循环遍历存储过程会导致冷融合

时间:2018-10-25 15:40:04

标签: sql sql-server coldfusion adobe

我想在Coldfusion中循环存储过程。我有以下代码循环查询。

I3

现在,查询已被如下所示的存储过程所代替,我想执行与上述代码相同的循环功能。在存储过程中,我确实有与上面相同的查询。先感谢您!

<cfquery name="rates" dbtype="query">
        select code, rate
  from application.qry.currency
  where code = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.origCode#" />
     or code = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.toCode#" />
</cfquery>
<cfloop query="rates">
    <cfscript>
            if (code == arguments.origCode) origRate = rate;
            if (code == arguments.toCode) toRate = rate;
        </cfscript>
</cfloop>

上面的完整代码:

<cfstoredproc procedure="usp_get_rates" datasource="#variables.dsn#">
        <cfprocparam cfsqltype="cf_sql_varchar" dbvarname="@origCode" type="in" value="#arguments.origCode#"/>
        <cfprocparam cfsqltype="cf_sql_varchar" dbvarname="@toCode" type="in" value="#arguments.toCode#" />
</cfstoredproc>

<cffunction name="convertCurrency" access="public" output="false" returntype="string">
  <cfargument name="amount" required="true" type="numeric" />
<cfargument name="origCode" required="true" type="string" />
<cfargument name="toCode" required="true" type="string" />
<cfscript>
        var theAmount = 0;
        var origRate = 0;
        var toRate = 0;
        var baseVal = 0;
        var newVal = 0;
        if (isNumeric(arguments.amount)) theAmount = arguments.amount;
        if (arguments.origCode == 'USD' && arguments.toCode == 'USD' || theAmount == 0) return theAmount;
        if (not isDefined("application.qry.currency")) initCurrencyRecordset();
    </cfscript>
<cfquery name="rates" dbtype="query">
        select code, rate
  from application.qry.currency
  where code = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.origCode#" />
     or code = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.toCode#" />
</cfquery>
<cfloop query="rates">
    <cfscript>
            if (code == arguments.origCode) origRate = rate;
            if (code == arguments.toCode) toRate = rate;
        </cfscript>
</cfloop>
<cfscript>
        if (origRate neq 0){
            baseVal = theAmount * (1 / origRate);
            newVal  = baseVal * toRate;
        }
        else {
            baseVal = theAmount * 1;
            newVal  = baseVal * toRate;
        }
        return newVal;
    </cfscript>

1 个答案:

答案 0 :(得分:1)

根据到目前为止的详细信息,完成您所要的.....

我假设您的存储过程看起来像这样:

CREATE PROCEDURE dbo.usp_get_rates @origCode varchar(20), @toCode varchar(20)
AS  
BEGIN 
  SET NOCOUNT ON ;
  SELECT code, rate
  FROM dbo.currency
  WHERE code IN ( @origCode, @toCode )
END;  
GO  

注意:您想用任何合适的数据库模式替换“ dbo”。但是,如果您要跨数据库查询(请参见上面有关application.qry.currency的评论),则将保持FROM调用不变,并在适当的架构中放置/引用存储过程。 < / p>

通过该过程,您的ColdFusion代码将类似于:

<cfstoredproc procedure="usp_get_rates" datasource="#variables.dsn#">
        <cfprocparam cfsqltype="cf_sql_varchar" dbvarname="@origCode" type="in" value="#arguments.origCode#">
        <cfprocparam cfsqltype="cf_sql_varchar" dbvarname="@toCode" type="in" value="#arguments.toCode#">
        <cfprocresult name="rates">
</cfstoredproc>

<cfscript>
  // Initialize your variables. They won't exist if your query has 0 rows.
  var origRate = 0 ; // Or expected datatype
  var toRate   = 0 ; // Or expected datatype

  for (var thisrow in rates) {
     if ( thisrow.code == arguments.origCode ) { origRate = thisrow.rate ; }
     if ( thisrow.code == arguments.toCode) { toRate = thisrow.rate ; }
  }
</cfscript>

由于您使用的是arguments范围,因此我假设此代码位于函数内部。这样一来,您就可以使用var关键字。

请注意,dbvarname自CFMX以来已被忽略,并已在CF11 Update 3中恢复。CF11具有JVM标志(-Dcoldfusion.ignoredbvarname)以继续忽略dbvarname,但该标志在CF2016 +中被忽略。

您可以使用简单的for循环遍历查询,但是正如我上面所说,这可能并不是您真正想要的。如果查询/存储过程返回多个结果,则将为多个返回的值覆盖origRatetoRate。也就是说,如果您的查询中包含[{code:"x",rate:41},{code:"x",rate:42}],它将覆盖rate的{​​{1}}。