2009-07-31 17 views
32

Quiero obtener una fila específica en un objeto ColdFusion Query sin hacer un bucle sobre ella.¿Puedo obtener una consulta fila por índice en ColdFusion?

me gustaría hacer algo como esto:

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

<cfset x = QueryName[5]> 

Pero me da un error diciendo que la consulta no es indexable por "5". Sé de hecho que hay más de 5 registros en esta consulta.

+1

CFLib.org al rescate de nuevo: http://cflib.org/udf/queryGetRow. Eso te permitirá hacer '' – ale

Respuesta

60

No se puede obtener una fila en CF < = 10. Debe obtener una columna específica.

<cfset x = QueryName.columnName[5]> 

Han pasado 8 años desde que he publicado esta respuesta, sin embargo. Aparentemente CF11 finalmente implementó esa característica. Ver FrankieZ's answer.

+0

Gracias, eso es lo que estaba buscando. –

+8

Prefiero la notación de corchetes para ambas filas y columnas, pero cualquier forma es igual de válida. QueryName ["columnName"] [5]. Necesitarás notación de corchetes si quieres usar una variable para el nombre de la columna, por ejemplo. – ale

+2

No es cierto. Puede obtener una fila, simplemente no usando las API estándar de CF. Y no podrá acceder a las columnas directamente por nombres de variables; deberá conocer el índice. Puede hacer myquery.getRow (0) para obtener la primera "coldfusion.sql.imq.Row" y myrow.getColumn (0) para obtener la primera columna. Row también tiene un método para obtener un Objeto [] que representa toda la fila. – Mark

7

usted tiene que convertir la consulta a una estructura en primer lugar:

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

espero que esto le apunta en la dirección correcta.

+0

pensé que esta era la única forma de hacer esto también, hasta que vi la respuesta de patrick – Kip

6

Sé que vuelvo a este hilo cada vez que Google "notación de partición cfquery". Aquí hay una función que escribí para manejar este caso usando la notación de corchetes. Espero que esto puede ayudar a alguien más también:

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

El REReplace es opcional, lo tengo ahí para limpiar comas para que no arruine la función arrayToList más adelante si usted tiene que usarlo.

4

Quería extraer una sola fila de una consulta y mantener los nombres de las columnas (por supuesto). Se trata de cómo lo resolví:

<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

También está CFLIB: http://cflib.org/udf/queryGetRow – ale

+0

¡Gracias! No sabía acerca de cflib – YZE91

6

Creo que hay una solución más simple ... que supongo que sabes sus nombres de columna y sólo desea que esta columna o que uno. Entonces no necesitas poner toda la fila en una estructura. Puede hacer referencia a la consulta por número de fila (recuerde que su 1 no está basado en 0).

yourQueryName [ "yourColumnName "] [rowNumber]

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

métodos previamente descritos para la obtención de datos de la consulta por nombre de columna y el número de fila (variables.myquery [" columnName"] [rowNumber ]) son correctos, pero no convenientes para obtener una fila completa de datos de consulta.

Estoy ejecutando Railo 4.1. Y esta es una buena solución. Lástima que esto no se puede hacer de la manera que quisiéramos obtener una fila completa de datos, pero el siguiente método nos permite obtener lo que queremos a través de algunos aros.

Cuando serializeJSON(variables.myquery) cambia la consulta a un objeto estructurado cfml con formato JSON con dos elementos: "Columnas" y "Datos". Ambas son matrices de datos. La matriz de "datos" es una matriz bidimensional para filas y luego datos columnares.

El problema es que ahora tenemos una cadena inutilizable. Entonces, si volvemos a serializarlo, NO es una consulta, sino una estructura regular utilizable en el formato descrito anteriormente.

Supongamos que ya tenemos una variable de consulta llamada 'variables.myquery'. A continuación, mira el siguiente código:

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

Ahora usted tiene la matriz bidimensional consiguiendo este:

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

y se obtiene una matriz fila consulta por conseguir esto:

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

O la última fila de esta manera:

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

y se puede obtener valores de las columnas individuales por número de orden de las columnas iteración:

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

Ahora bien, esto podría ser lento y posiblemente imprudente con grandes resultados de la consulta, pero esto es una solución fresca, no obstante.

7

Esto ahora se puede lograr de ColdFusion 11 a través de 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 answer. Me da vergüenza decir que no estaba al tanto de esta función. cf11 sigue entregando! – jyoseph

+0

@jyoseph Ahora bien, solo ellos pueden seguir como lucee, y agregar un 'lazy =" true "' a la etiqueta cfquery para que pueda tirar miles de filas sin preocuparse por la fusión fría tratando de devorar toda la memoria. – FrankerZ

-1

Mira la documentación de queryGetRow. Acepta un objeto de consulta y un índice de la fila con la referencia de la primera fila con el índice de 1 (NO 0). Se requiere que el índice utilizado de esta forma sea un entero positivo.

<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) /> 
Cuestiones relacionadas