ColdFusion Queryオブジェクトの特定の行をループせずに取得したい。
私はこのようなことをしたいです:
<cfquery name="QueryName" datasource="ds">
SELECT *
FROM tablename
</cfquery>
<cfset x = QueryName[5]>
しかし、クエリが「5」でインデックス付けできないというエラーが表示されます。このクエリには5つ以上のレコードがあることは事実です。
CF <= 10では行を取得できません。特定の列を取得する必要があります。
<cfset x = QueryName.columnName[5]>
ただし、この回答を投稿してから8年が経ちました。どうやらCF11は最終的にその機能を実装しました。 FrankieZの答え を参照してください。
これは、coldfusion 11で QueryGetRow を使用して実現できます。
<cfquery name="myQuery" result="myresult" datasource="artGallery" fetchclientinfo="yes" >
select * from art where ARTID >
<cfqueryparam value="2" cfsqltype="CF_SQL_INTEGER">
</cfquery>
<cfdump var="#myQuery#" >
<cfset data = QueryGetRow(myQuery, 1) >
<cfdump var="#data#" >
もっと簡単な解決策があると思います...あなたはあなたの列名を知っていて、この列またはその列だけが欲しいと思います。次に、行全体を構造体に配置する必要はありません。行番号でクエリを参照できます(0ではなく1に基づいていることに注意してください)。
<cfoutput>
#mycontacts["Name"][13]#
#mycontacts["HomePhone"][13]#
</cfoutput>
最初にクエリを構造体に変換する必要があります。
<cfscript>
function GetQueryRow(query, rowNumber) {
var i = 0;
var rowData = StructNew();
var cols = ListToArray(query.columnList);
for (i = 1; i lte ArrayLen(cols); i = i + 1) {
rowData[cols[i]] = query[cols[i]][rowNumber];
}
return rowData;
}
</cfscript>
<cfoutput query="yourQuery">
<cfset theCurrentRow = GetQueryRow(yourQuery, currentRow)>
<cfdump var="#theCurrentRow#">
</cfoutput>
これがあなたを正しい方向に向けることを願っています。
Googleで「cfqueryブラケット表記法」を使用すると、いつでもこのスレッドに戻ることがわかります。これは、ブラケット表記を使用してこのケースを処理するために作成した関数です。これが他の人にも役立つことを願っています:
<cffunction name="QueryGetRow" access="public" returntype="array" hint="I return the specified row's data as an array in the correct order">
<cfargument name="query" required="true" type="query" hint="I am the query whose row data you want">
<cfargument name="rowNumber" required="true" hint="This is the row number of the row whose data you want">
<cfset returnArray = []>
<cfset valueArray = []>
<cfset cList = ListToArray(query.ColumnList)>
<cfloop from="1" to="#ArrayLen(cList)#" index="i">
<cfset row = query["#cList[i]#"][rowNumber]>
<cfset row = REReplace(row, "(,)", " ")>
<cfset returnArray[i] = row>
<cfset i++>
</cfloop>
<cfreturn returnArray>
</cffunction>
REReplaceはオプションです。使用する必要がある場合に後でarrayToList関数を台無しにしないように、コンマをクレンジングするためにREReplaceを用意しています。
クエリから単一の行を抽出し、列名を保持したかった(もちろん)。これは私がそれを解決した方法です:
<cffunction name="getQueryRow" returntype="query" output="no">
<cfargument name="qry" type="query" required="yes">
<cfargument name="row" type="numeric" required="yes">
<cfset arguments.qryRow=QueryNew(arguments.qry.columnlist)>
<cfset QueryAddRow(arguments.qryRow)>
<cfloop list="#arguments.qry.columnlist#" index="arguments.column">
<cfset QuerySetCell(arguments.qryRow,arguments.column,Evaluate("arguments.qry.#arguments.column#[arguments.row]"))>
</cfloop>
<cfreturn arguments.qryRow>
</cffunction>
列名と行番号(variables.myquery ["columnName"] [rowNumber])でクエリデータを取得するための前述のメソッドは正しいですが、クエリデータの行全体を取得するには便利ではありません。
Railo 4.1を実行しています。そして、これはクールなソリューションです。残念ながら、これでは完全なデータ行を取得する方法を実行できませんが、次の方法を使用すると、数回のフープで必要なものを取得できます。
serializeJSON(variables.myquery)
を実行すると、クエリがJSON形式のcfml structオブジェクトに変更されます。このオブジェクトには、「列」と「データ」という2つの項目があります。これらは両方ともデータの配列です。 「データ」配列は、行と列データの2次元配列です。
問題は、現在使用できない文字列があることです。その後、再シリアル化すると、クエリではなく、上記の形式で使用できる通常の構造体になります。
「variables.myquery」という名前のクエリ変数が既にあるとします。次に、次のコードを見てください。
<cfset variables.myqueryobj = deserializeJSON(serializeJSON(variables.myquery)) />
これで、2次元配列を取得できます:
<cfset variables.allrowsarray = variables.myqueryobj.data />
そして、あなたはこれを取得することで1つのクエリ行配列を取得します:
<cfset variables.allrowsarray = variables.myqueryobj.data[1] />
またはこの最後の行:
<cfset variables.allrowsarray = variables.myqueryobj.data[variables.myquery.recordCount] />
また、列の順序番号の反復によって個々の列の値を取得できます。
<cfset variables.allrowsarray = variables.myqueryobj.data[1][1] />
現在、これは遅く、おそらく大きなクエリ結果では賢明ではないかもしれませんが、それでもなお、これはクールなソリューションです。
queryGetRow のドキュメントをご覧ください。クエリオブジェクトと、最初の行が1(NOT 0)のインデックスで参照される行のインデックスを受け入れます。この方法で使用されるインデックスは、正の整数である必要があります。
<cfquery name="QueryName" datasource="ds">
SELECT *
FROM tablename
</cfquery>
<!---
This would retrieve the first record of the query
and store the record in a struct format in the variable 'x'.
--->
<cfset x = queryGetRow(QueryName, 1) />
<!---
This is an alternative using the member method form of queryGetRow
--->
<cfset x = QueryName.getRow(1) />