【问题标题】:How to compare column values in cfscript?如何比较cfscript中的列值?
【发布时间】:2018-07-26 15:59:17
【问题描述】:

我想循环查询并比较列值。以下是 CFML 代码示例:

<cfquery name="qryUserPerm" datasource="#Application.dsn#">
    SELECT AccessType, AccessLevel, State, City, Building
    FROM Permissions
    WHERE AccountID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(session.AccountID)#">
</cfquery>

<cfset local.permissionType = "">
<cfset local.permissionLevel = "">
<cfset local.permissionList = "">

<cfif qryUserPerm.AccessLevel EQ "S">
     <cfset local.permissionType = qryUserPerm.AccessType>
     <cfset local.permissionLevel = qryUserPerm.AccessLevel>
     <cfset local.permissionList = qryUserPerm.State>
<cfelseif qryUserPerm.AccessLevel EQ "C">
     <cfset local.permissionType = qryUserPerm.AccessType>
     <cfset local.permissionLevel = qryUserPerm.AccessLevel>
     <cfset local.permissionList = ListRemoveDuplicates(ValueList(permissionList,qryUserPerm.City))>
<cfelseif qryUserPerm.AccessLevel EQ "B">
     <cfset local.permissionType = qryUserPerm.AccessType>
     <cfset local.permissionLevel = qryUserPerm.AccessLevel>
     <cfset local.permissionList = ListRemoveDuplicates(ValueList(permissionList,qryUserPerm.Building))>
</cfif>

上面的代码应该被翻译成cfscript,我已经做到了,但不知道如何访问列值。

<cfscript>
    public string function permissionList(required string AccountID) {
        local.fnResults = "";
        local.permissionList = "";

        try{
            local.qryPermissions = new Query();
            local.qryPermissions.setDatasource("#Application.dsn#");
            local.qryPermissions.setSQL("SELECT AccessType, AccessLevel, State, City, Building FROM Permissions WHERE AccountID = :AccountID");
            local.qryPermissions.addParam(name="AccountID",value="#trim(arguments.AccountID)#",cfsqltype="cf_sql_idstamp");
            local.qryRes = qryPermissions.execute();

            for ( i = 1 ; i <= qryRes.getResult().recordCount ; i++ ) {
                if(qryRes["AccessLevel"][i] EQ "S"){
                    local.permissionList = "";
                }else if(qryRes["AccessLevel"][i] EQ "S"){
                    local.permissionList = ListRemoveDuplicates(ValueList(qryRes.Agency,","));
                }else if(qryRes["AccessLevel"][i] EQ "C"){
                    local.permissionList = ListRemoveDuplicates(ValueList(qryRes.District,","));
                }else if(qryRes["AccessLevel"][i] EQ "B"){
                    local.permissionList = ListRemoveDuplicates(ValueList(qryRes.Building,","));
                }
            }

            local.fnResults = permissionList;
        }catch(any e){
            local.fnResults = e.message;
            //writeOutput(e.message);    
        }

        return fnResults;
    }

    writeOutput(permissionList(AccountID));
</cfscript>

如果有人可以帮忙,请告诉我。

【问题讨论】:

  • 如果您的意思是分配或访问值,您的代码已经在此处访问列值:qryRes["AccessLevel"][i],使用语法 queryName["ColumnName"][RowNumber]。只需在需要的地方使用相同的语法即可。
  • 我必须比较accessLevel 列值并检查它是S 州、C 城市还是B 建筑物。基于该值将分配给 permissionList 变量。那有意义吗?代码不起作用,我很困惑,因为这是 CFML 中的正确语法。
  • 是的,逻辑是有道理的,但我不知道哪条线不起作用。 (顺便说一句,我在你的另一个线程上提出的关于 SQL 中的 CASE 的建议将使所有这些都没有实际意义......)
  • @Ageax 这是我在 catch 块 Element AccessLevel is undefined in a Java object of type class coldfusion.runtime.TemplateProxy. 中遇到的错误。
  • (更新)哦!我认为问题在于local.qryRes 不包含查询。混淆地调用execute() 不会返回查询,但execute().getResult() 会。尝试将分配更改为local.qryRes = qryPermissions.execute().getResult()。不要忘记从 for 循环中删除 getResult()。

标签: coldfusion cfml cfquery cfloop


【解决方案1】:

你也可以使用:

local.qryPermissions = queryExecute(
        "SELECT AccessType, AccessLevel, State, City, Building
        FROM Permissions 
        WHERE AccountID = :AccountID" ,
        {AccountID={value="#trim(arguments.AccountID)#", cfsqltype="cf_sql_idstamp"}}  // Or "?" and "[value=xxx,cfsqltype=xxx]"
    ) ;

然后在没有循环的情况下构建您的权限部分:

  local.permissionType = qryPermissions.AccessType ;
  local.permissionLevel = qryPermissions.AccessLevel ;

  switch( qryPermissions.AccessLevel ) {
    case "S" :  local.permissionList = qryPermissions.State ;
      break ;
    case "C" :  local.permissionList = ListRemoveDuplicates(ValueList(qryPermissions.City)) ;
      break ;
    case "B" :  local.permissionList = ListRemoveDuplicates(ValueList(qryPermissions.Building)) ;
      break ;
  }

另请参阅我关于其他问题的笔记,关于潜在的无意的、半相关的数据。

【讨论】:

  • 好的,我承诺 @Ageax 和我不是同一个人。我们也不共享同一个大脑。虽然看起来经常是这样。
【解决方案2】:

(来自 cmets ...)

问题是local.qryRes 实际上不包含查询对象。令人困惑的是,调用 execute() 不会返回查询,但调用 execute().getResult() 会。尝试从以下位置更改分配:

local.qryRes = qryPermissions.execute();

收件人:

local.qryRes = qryPermissions.execute().getResult();

其他一些观察:

  1. local 限定所有函数变量非常重要,包括循环索引 i。否则,如果组件存储在共享范围内,您可能会得到一些奇怪且不可预测的结果。

  2. 虽然我不认为循环是必要的,但如果您使用循环,请考虑更简单的for..in 语法,而不是索引循环:

    for (local.row in local.qryPermissions ) {
        if (local.row.AccessType eq "S") {
            //... code here 
        }
        .... 
    }
    
  3. 由于访问字段密切相关,我可能会让函数返回一个包含所有三个键(AccessType、AccessLevel、PermissionList)的结构,而不是三个单独的函数。

  4. 不要使用循环,而是考虑使用其他线程上的建议之一, Best way to store permissions for the user account?

【讨论】:

  • 另外,如果您使用的是 CF11+,请考虑使用较新的 QueryExecute() 而不是 new Query()(较旧的组件)。
猜你喜欢
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 2016-01-25
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
相关资源
最近更新 更多