¿Puedo obtener una fila de consulta por índice en ColdFusion?
cfml cfquery (8)
Quiero obtener una fila específica en un objeto ColdFusion Query sin hacer un bucle sobre ella.
Me gustaría hacer algo como esto:
<cfquery name="QueryName" datasource="ds">
SELECT *
FROM tablename
</cfquery>
<cfset x = QueryName[5]>
Pero me está dando un error al decir que la consulta no es indexable por "5". Sé de hecho que hay más de 5 registros en esta consulta.
Consulte 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) />
Creo que hay una solución más simple ... supongo que sabes los nombres de tus columnas y solo quieres esta columna o esa. 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>
Esto ahora se puede lograr en 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#" >
Los métodos descritos anteriormente para obtener datos de consulta por nombre de columna y 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)
JSON 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''. Luego mira el siguiente código:
<cfset variables.myqueryobj = deserializeJSON(serializeJSON(variables.myquery)) />
Ahora obtienes la matriz bidimensional obteniendo esto:
<cfset variables.allrowsarray = variables.myqueryobj.data />
Y obtienes una matriz de fila de consulta obteniendo 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 puede obtener valores de columna individuales por iteración de número de orden de columna:
<cfset variables.allrowsarray = variables.myqueryobj.data[1][1] />
Ahora esto puede ser lento y posiblemente imprudente con los resultados de consultas grandes, pero esta es una solución genial, no obstante.
No 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 publiqué esta respuesta, sin embargo. Aparentemente CF11 finalmente implementó esa característica. Ver la respuesta de FrankieZ .
Primero debe convertir la consulta en una estructura:
<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 te indique la dirección correcta.
Quería extraer una sola fila de una consulta y mantener los nombres de las columnas (por supuesto). Así es como 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>
Sé que vuelvo a este hilo cada vez que Google "notación de corchery corchete". Aquí hay una función que escribí para manejar este caso usando la notación de corchetes. Con suerte, esto también puede ayudar a alguien más:
<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 las comas para que no estropee la función arrayToList más adelante si tiene que usarlo.