如何在带有 cfquery 列的结构中设置动态键名?
How to set a dynamic key name in a struct with cfquery column?
我有一个结构,我想用 cfquery 列 recID
替换 currentRow
键。此列是整数,在 sql
table 中自动递增。出于某种原因,我的代码无法创建具有唯一键的结构。这是我的代码:
<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
}
}
我想知道为什么第一个代码无法产生正确的输出?为什么带有附加字符串的第二个版本可以正常工作?有什么办法可以解决或解决这个问题吗?
您需要做的就是将变量fnAccounts
定义为一个结构体。
<cfset fnAccounts = {}>
没有定义,CF 可以自由 select 任何看起来合适的东西。
<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 就可以将变量视为结构。
我的解决方案是基于 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
这是一个更通用的答案,适用于任何查询。我将结构键设置为小写,因为我通常使用这种功能将查询数据传递给 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>
在引用查询数据时,将数据放入结构数组(而不是 struct if structs)对我来说似乎更直观。
我有一个结构,我想用 cfquery 列 recID
替换 currentRow
键。此列是整数,在 sql
table 中自动递增。出于某种原因,我的代码无法创建具有唯一键的结构。这是我的代码:
<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
}
}
我想知道为什么第一个代码无法产生正确的输出?为什么带有附加字符串的第二个版本可以正常工作?有什么办法可以解决或解决这个问题吗?
您需要做的就是将变量fnAccounts
定义为一个结构体。
<cfset fnAccounts = {}>
没有定义,CF 可以自由 select 任何看起来合适的东西。
<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 就可以将变量视为结构。
我的解决方案是基于 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
这是一个更通用的答案,适用于任何查询。我将结构键设置为小写,因为我通常使用这种功能将查询数据传递给 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>
在引用查询数据时,将数据放入结构数组(而不是 struct if structs)对我来说似乎更直观。