如何使用cfquery列在结构中设置动态密钥名称?

时间:2018-05-16 16:34:45

标签: struct coldfusion cfquery coldfusion-2016

我有结构,我想用cfquery列currentRow替换recID键。此列是整数,在sql表中自动递增。由于某种原因,我的代码无法使用唯一键创建结构。这是我的代码:

<cfquery name="qryAccounts" datasource="myDB">
   SELECT RecID, FirstName, LastName
   FROM Accounts WITH (NOLOCK)
</cfquery>

<cfloop query="qryAccounts">
    <cfset fnAccounts[RecID] = StructNew()>
    <cfset fnAccounts[RecID].RecordID = RecID>
    <cfset fnAccounts[RecID].FirstName = FirstName>
    <cfset fnAccounts[RecID].LastName = LastName>
</cfloop>

上面的代码产生了这个结果:

[
  {
    "FIRSTNAME": "Mike",
    "LASTNAME": "Richards",
    "RECORDID": 1
  },
  null,
  null,
  null,
  {
    "FIRSTNAME": "John",
    "LASTNAME": "Matt",
    "RECORDID": 6
  }
]

然后我试着这样做:

<cfquery name="qryAccounts" datasource="myDB">
   SELECT RecID, FirstName, LastName
   FROM Accounts WITH (NOLOCK)
</cfquery>

<cfloop query="qryAccounts">
    <cfset fnAccounts["ID"&RecID] = StructNew()>
    <cfset fnAccounts["ID"&RecID].RecordID = RecID>
    <cfset fnAccounts["ID"&RecID].FirstName = FirstName>
    <cfset fnAccounts["ID"&RecID].LastName = LastName>
</cfloop>

上面的代码产生了正确的输出:

{
  "ID1": {
  "FIRSTNAME": "Mike",
  "LASTNAME": "Richards",
  "RECORDID": 1
  },
"ID6": {
  "FIRSTNAME": "John",
  "LASTNAME": "Matt",
  "RECORDID": 6
  }
}

我想知道为什么第一个代码无法产生正确的输出?为什么附加字符串的第二个版本工作正常有没有办法解决或解决这个问题?

3 个答案:

答案 0 :(得分:4)

您需要做的就是将变量fnAccounts定义为结构。

<cfset fnAccounts = {}>

如果没有这个定义,CF可以自由选择它看起来合适的东西。

<cfquery name="qryAccounts" datasource="myDB">
   SELECT RecID, FirstName, LastName
   FROM Accounts WITH (NOLOCK)
</cfquery>

<cfset fnAccounts = {}>
<cfloop query="qryAccounts">
    <cfset fnAccounts[RecID] = StructNew()>
    <cfset fnAccounts[RecID].RecordID = RecID>
    <cfset fnAccounts[RecID].FirstName = FirstName>
    <cfset fnAccounts[RecID].LastName = LastName>
</cfloop>

由于您尝试将RecID用作整数值键,因此它类似于我们访问数组的方式(fnAccounts[1]数组中的第一个位置)。将fnAccounts定义为结构后,ColdFusion可以将变量视为结构。

DEMO

答案 1 :(得分:4)

这是一个更通用的答案,适用于任何查询。我把结构键放在小写的情况下,因为我通常使用这种功能将查询数据传递给json。

<cfscript>
    function queryToArray(q) {
        var ret = [];
        var cols = listToArray( q.columnList );
        for(var i in q) {
            var row = {};
            for(var col in cols ) {
                row[lcase(col)] =  i[col];
            }
            arrayAppend(ret, row);
        }
        return ret;
    }
</cfscript>

在引用查询数据时,将数据放入结构数组(而不是结构中的结构)似乎更直观。

答案 2 :(得分:2)

我的解决方案基于RRK,但我更喜欢cfscript

<cfquery name="qryAccounts" datasource="myDB">
  SELECT RecID, FirstName, LastName
  FROM Accounts WITH (NOLOCK)
</cfquery>

<cfscript>
  fnAccounts = {};
  for (i in qryAccounts) {
     fnAccounts[i.RecID] = {
       RecordID : i.RecID,
       FirstName : i.FirstName,
       LastName : i.LastName
       };
     } // end for 
</cfscript>

cfquery也可以移动到cfscript