2009-07-31 11 views
32

Ich möchte eine bestimmte Zeile in einem ColdFusion-Abfrageobjekt abrufen, ohne sie zu durchlaufen.Kann ich in ColdFusion eine Abfrage Zeile für Index abrufen?

Ich mag so etwas wie dies zu tun:

<cfquery name="QueryName" datasource="ds"> 
SELECT * 
FROM tablename 
</cfquery> 

<cfset x = QueryName[5]> 

Aber es ist mir einen Fehler geben zu sagen, dass die Abfrage von „5“ nicht Wende ist. Ich weiß in der Tat, dass es mehr als 5 Datensätze in dieser Abfrage gibt.

+1

CFLib.org wieder zur Rettung: http://cflib.org/udf/queryGetRow. Das lässt dich '' machen cfset x = queryGetRow (QueryName, 5)> ' – ale

Antwort

60

Sie können keine Zeile in CF erhalten < = 10. Sie müssen eine bestimmte Spalte abrufen.

Es ist schon 8 Jahre her, dass ich diese Antwort gepostet habe. Anscheinend hat CF11 dieses Feature endlich implementiert. Siehe FrankieZ's answer.

+0

Danke, das ist, was ich gesucht habe. –

+8

Ich bevorzuge Klammern Notation für beide Zeilen und Spalten, aber beide Wege ist genauso gültig. Abfragename ["columnName"] [5]. Sie benötigen Klammernotation, wenn Sie beispielsweise eine Variable für den Spaltennamen verwenden möchten. – ale

+2

Nicht wahr. Sie können eine Zeile erhalten, ohne die Standard-CF-APIs zu verwenden. Und Sie können nicht direkt auf die Spalten nach Variablennamen zugreifen - Sie müssen den Index kennen. Sie können myquery.getRow (0) ausführen, um die erste "coldfusion.sql.imq.Row" und myrow.getColumn (0) abzurufen, um die erste Spalte abzurufen. Row verfügt auch über eine Methode, um ein Object [] zu erhalten, das die gesamte Zeile darstellt. – Mark

7

Sie haben die Abfrage auf eine Struktur konvertieren zuerst:

<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> 

Hope this Punkte, die Sie in die richtige Richtung.

+0

Ich dachte, das wäre der einzige Weg, dies auch zu tun, bis ich Patrick Antwort sah – Kip

6

Ich weiß, ich komme zu diesem Thread jedes Mal, wenn ich Google "cfquery Bracket Notation". Hier ist eine Funktion, die ich geschrieben habe, um diesen Fall mit Bracket-Notation zu behandeln. Hoffentlich jemand helfen kann sonst auch:

<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> 

Die REReplace optional ist, ich habe es dort in Kommata zu reinigen, so dass es nicht die ArrayToList Funktion nicht vermasseln später, wenn Sie es zu benutzen.

4

Ich wollte eine einzelne Zeile aus einer Abfrage extrahieren und die Spaltennamen behalten (natürlich). Dies ist, wie ich es gelöst:

<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> 
+0

Es gibt auch CFLIB: http://cflib.org/udf/queryGetRow – ale

+0

Danke! Ich wusste nicht über cflib – YZE91

6

Ich denke, es ist eine einfachere Lösung ... Ich vermute, Sie Ihre Spaltennamen kennen und wollen nur diese Spalte oder dass man. Dann müssen Sie die ganze Zeile nicht in eine Struktur einfügen. Sie können die Abfrage nach Zeilennummer referenzieren (denken Sie daran, dass 1 nicht 0 ist).

yourQueryName [ "yourColumnName "] [rowNumber]

<cfoutput> 
    #mycontacts["Name"][13]# 
    #mycontacts["HomePhone"][13]# 
</cfoutput> 
1

Methods vorher zum Erhalten von Abfragedaten durch Spaltennamen und die Zeilennummer (variables.myquery beschrieben [" column"] [rowNumber ]) sind korrekt, aber nicht praktisch, um eine vollständige Reihe von Abfragedaten zu erhalten.

Ich laufe Railo 4.1. Und das ist eine coole Lösung. Schade, dass wir das nicht so machen können, wie wir es wollen, um eine ganze Reihe von Daten zu bekommen, aber die folgende Methode erlaubt es uns, durch einige Reifen zu bekommen, was wir wollen.

Wenn Sie serializeJSON(variables.myquery) ändern, ändert sich die Abfrage in ein JSON-formatiertes cfml-struct-Objekt mit zwei Elementen: "Columns" und "Data". Beides sind Datenfelder. Das "Daten" -Array ist ein zweidimensionales Array für Zeilen und dann für spaltenförmige Daten.

Das Problem ist, dass wir jetzt eine unbrauchbare Zeichenfolge haben. Wenn wir es dann erneut serialisieren, ist es keine Abfrage, sondern eine brauchbare reguläre Struktur in dem oben beschriebenen Format.

Angenommen, wir haben bereits eine Abfragevariable mit dem Namen 'variables.myquery'. Schauen Sie sich den folgenden Code:

<cfset variables.myqueryobj = deserializeJSON(serializeJSON(variables.myquery)) /> 

Jetzt können Sie die zweidimensionale Matrix erhalten, indem man diese:

<cfset variables.allrowsarray = variables.myqueryobj.data /> 

Und Sie eine Abfragezeile Array erhalten, indem diese bekommen:

<cfset variables.allrowsarray = variables.myqueryobj.data[1] /> 

ODER die letzte Zeile auf diese Weise:

<cfset variables.allrowsarray = variables.myqueryobj.data[variables.myquery.recordCount] /> 

Und Sie können durch Spalte Bestellnummer Iteration einzelne Spaltenwerte erhalten:

<cfset variables.allrowsarray = variables.myqueryobj.data[1][1] /> 

Jetzt könnte dies langsam und möglicherweise unklug mit großen Abfrageergebnissen, aber das ist eine coole Lösung dennoch.

7

Dies kann nun in Coldfusion 11 über 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#" > 
+1

Killer-Antwort. Ich schäme mich zu sagen, dass ich mir dieser Funktion nicht bewusst war. cf11 liefert weiter! – jyoseph

+0

@jyoseph Jetzt, wenn sie nur wie lucee folgen können, und fügen Sie ein 'lazy =" true "' zum cfquery Tag hinzu, so dass ich Tausende von Reihen ziehen kann, ohne sich Gedanken über Coldfusion zu machen und den gesamten Speicher aufzufressen. – FrankerZ

-1

Schauen Sie sich die Dokumentation für queryGetRow erreicht werden. Es akzeptiert ein Abfrageobjekt und einen Index der Zeile, wobei die erste Zeile mit dem Index 1 referenziert wird (NOT 0). Der auf diese Weise verwendete Index muss eine positive ganze Zahl sein.

<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) /> 
Verwandte Themen