Je veux obtenir une ligne spécifique dans un objet de requête ColdFusion sans boucler dessus.
Je voudrais faire quelque chose comme ça:
<cfquery name="QueryName" datasource="ds">
SELECT *
FROM tablename
</cfquery>
<cfset x = QueryName[5]>
Mais cela me donne une erreur disant que la requête n'est pas indexable par "5". Je sais pertinemment qu'il y a plus de 5 enregistrements dans cette requête.
Vous ne pouvez pas obtenir une ligne dans CF <= 10. Vous devez obtenir une colonne spécifique.
<cfset x = QueryName.columnName[5]>
Cela fait cependant 8 ans que j'ai posté cette réponse. Apparemment, CF11 a finalement implémenté cette fonctionnalité. Voir réponse de FrankieZ .
Cela peut maintenant être accompli dans Coldfusion 11 via 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#" >
Je pense qu'il existe une solution plus simple ... Je suppose que vous connaissez les noms de vos colonnes et que vous souhaitez uniquement cette colonne ou celle-là. Ensuite, vous n'avez pas besoin de mettre la ligne entière dans une structure. Vous pouvez référencer la requête par numéro de ligne (rappelez-vous que son 1 est basé sur non 0).
<cfoutput>
#mycontacts["Name"][13]#
#mycontacts["HomePhone"][13]#
</cfoutput>
Vous devez d'abord convertir la requête en une structure:
<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>
J'espère que ça vous indique la bonne direction.
Je sais que je reviens à ce fil chaque fois que je Google "cfquery bracket notation". Voici une fonction que j'ai écrite pour gérer ce cas en utilisant la notation entre crochets. J'espère que cela peut aussi aider quelqu'un d'autre:
<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>
Le REReplace est facultatif, je l'ai là pour nettoyer les virgules afin qu'il ne visse pas la fonction arrayToList plus tard si vous devez l'utiliser.
Je voulais extraire une seule ligne d'une requête et conserver les noms des colonnes (bien sûr). Voici comment je l'ai résolu:
<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>
Les méthodes décrites précédemment pour obtenir des données de requête par nom de colonne et numéro de ligne (variables.myquery ["columnName"] [rowNumber]) sont correctes, mais pas pratiques pour obtenir une ligne complète de données de requête.
J'utilise Railo 4.1. Et c'est une bonne solution. Dommage que cela ne puisse pas être fait de la manière que nous souhaiterions obtenir immédiatement une ligne complète de données, mais la méthode suivante nous permet d'obtenir ce que nous voulons à travers quelques cerceaux.
Lorsque vous serializeJSON(variables.myquery)
il change la requête en un objet struct cfml au format JSON avec deux éléments: "Colonnes" et "Données". Ces deux éléments sont des tableaux de données. Le tableau "données" est un tableau à deux dimensions pour les lignes, puis les données en colonnes.
Le problème est que nous avons maintenant une chaîne inutilisable. Ensuite, si nous le re-sérialisons, ce n'est PAS une requête, mais plutôt une structure régulière utilisable dans le format décrit ci-dessus.
Supposons que nous ayons déjà une variable de requête nommée 'variables.myquery'. Regardez ensuite le code suivant:
<cfset variables.myqueryobj = deserializeJSON(serializeJSON(variables.myquery)) />
Maintenant, vous obtenez le tableau bidimensionnel en obtenant ceci:
<cfset variables.allrowsarray = variables.myqueryobj.data />
Et vous obtenez un tableau de lignes de requête en obtenant ceci:
<cfset variables.allrowsarray = variables.myqueryobj.data[1] />
OU la dernière ligne de cette façon:
<cfset variables.allrowsarray = variables.myqueryobj.data[variables.myquery.recordCount] />
Et vous pouvez obtenir des valeurs de colonne individuelles par itération du numéro d'ordre des colonnes:
<cfset variables.allrowsarray = variables.myqueryobj.data[1][1] />
Maintenant, cela peut être lent et peut-être imprudent avec des résultats de requête volumineux, mais c'est néanmoins une solution intéressante.
Consultez la documentation de queryGetRow . Il accepte un objet de requête et un index de la ligne avec la première ligne étant référencée avec l'index de 1 (PAS 0) L'index utilisé de cette façon doit être un entier positif.
<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) />