Ser Programador

Como utilizar o loop do ColdFusion para percorrer resultado de queries?

Vamos explorar as duas principais formas de obter o resultado de queries com o ColdFusion utilizando o cfloop.


O ColdFusion tem duas formas nas quais vejo como principais para percorrer o resultado de queries com uso do cfloop.


A primeira das formas é percorrendo a query em si, e o ColdFusion converterá automaticamente os campos da query em variáveis dento do escopo do cfloop. A segunda forma é percorrendo a própria struct resultado da execução da query, utilizando o índice de iteção do cfloop para resgatar os valores dos campos de cada índice da struct.


Para este exemplo, vamos considerar uma tabela tb_usuarios, onde claramente são registrados os usuários de um sistema fictício:

		------------------------------------
		|            tb_usuarios           |
		------------------------------------
		| id_usuario | nome   | nascimento |
		------------------------------------
		|          1 | Alan   | 1999-01-01 |
		------------------------------------
		|          2 | Victor | 1999-01-02 |
		------------------------------------
		|          1 | José   | 1999-01-03 |
		------------------------------------
	

Antes de percorrer algum resultado de query, precisamos executar a query em si. Vamos efetuar uma consulta na tabela acima através da seguinte query:

		<cfquery datasource="dbconnection" name="querydata">
			select
				id_usuario,
				nome,
				nascimento
			from tb_usuarios
		</cfloop>
	

A consulta acima irá guardar o resultado da consulta em forma de struct dentro da variável querydata, fornecido como valor para o atributo name (é literalemente um nome que damos à query);

O atributo datasource recebe como valor o nome de uma conexão com banco de dados já registrada no painel de conexões do CfAdmin do ambiente onde o ColdFusion está sendo executado;


Para saber como registrar uma conexão com banco de dados no painel de conexões do ColdFusion Administrator, NESTE ARTIGO você aprende como.


Uma vez com a query executada, já podemos percorrer a struct resultante da consulta, para então ter acesso aos dados obtidos no banco de dados. Vamos ver primeiro pela forma menos prática. Esta forma é útil se você deseja ter acesso aos índices de cada linha da query:

		<cfloop index="i" from="1" to="#querydata.recordcount#">
			<cfoutput>#querydata.nome[i]#;<br></cfoutput>
		</cfloop>
	

Fornecemos para o atributo index o nome da variável que desejamos que seja guardado o índice atual da iteração do loop, que neste caso usamos a variável "i";

Arrays e também structs no ColdFusion sempre começam com índice 1, portanto estamos fornecendo 1 para o parâmetro from;

Utilizamos a chave recordcount do objeto resultante da consulta para obter a quantidade total de registros que a query retornou, e fornecemos esse valor para o parâmetro to do cfloop;

Structs tem uma estrutura bastante diferente de arrays e objetos nas demais linguagens. Portanto, para obter o valor de uma linha através do índice de linha, precisamos fornecer o índice ao final da "chave" que desejamos obter do "objeto" struct resultante da query (e não no objeto em si como faríamos em outras linguagens);


O resultado será algo parecido com:

		Alan;
		Victor;
		José;
	


Podemos também construir textos utilizando vários campos da query numa mesma iteração:

		<cfloop index="i" from="1" to="#querydata.recordcount#">
			<cfoutput>O usuário #querydata.nome[i]# (de ID #querydata.id_usuario[i]#), nasceu em #querydata.nascimento[i]#;<br></cfoutput>
		</cfloop>
	

O resultado será algo parecido com:

		O usuário Alan (de ID 1), nasceu em 1999-01-01;
		O usuário Victor (de ID 2), nasceu em 1999-01-02;
		O usuário José (de ID 3), nasceu em 1999-01-03;
	

Podemos inclusive construir um array para fornecer em forma de JSON no caso de uma requisição HTTP vinda do front-end:

		<cfset dataToProvide = ArrayNew(1)>
		<cfloop index="i" from="1" to="#querydata.recordcount#">
			<cfset dataToProvide[i]['id_usuario'] = querydata.id_usuario[i]>
			<cfset dataToProvide[i]['nome'] = querydata.nome[i]>
			<cfset dataToProvide[i]['nascimento'] = querydata.nascimento[i]>
		</cfloop>

		<cfoutput>#SerializeJSON(dataToProvide)#</cfoutput>
	

Com uso do cfset instanciamos uma variável chamada dataToProvide, e utilizamos a função ArrayNew para criar um novo array, fornecendo 1 como parâmetro para informar que nosso array terá 1 dimensão, e utilizaremos cada índice desse array como um objeto, inclusive podendo adicionar novos arrays dentro deste objeto;

Dentro do loop, utilizamos cfset para setar a chave do array (id_usuario, nome, e nascimento) no índice "i" deste array (linha do array), atribuindo como valor para essa "chave" o valor do mesmo campo retornado pela query na struct;

Utilizamos a função SerializeJSON para converter nosso array em JSON e fazemos o output na tela com uso do cfoutput;


Tecnicamente usar a função ArrayNew com uma dimensão para criar um array e tratá-lo como array de múltiplas dimensões não causa erros de código. Portanto pode-se utilizar usando ArrayNew(1) e conforme a necessidade guardar outros arrays dentro deste, tranquilamente, de acordo com a necessidade. Porém se utilizar ArrayNew(2) para criar um array de duas dimensões você obrigatoriamente precisará trabalhar com arrays no segundo nível.


O resultado do output do bloco de código acima será algo parecido com:

		[{"id_usuario":1,"nascimento":"1999-01-01","nome":"Alan"},{"id_usuario":2,"nascimento":"1999-01-02","nome":"Victor"},{"id_usuario":3,"nascimento":"1999-01-03","nome":"José"}]
	


Vejamos agora a forma mais prática de percorrer uma struct resultante de uma consulta no banco de dados. Esta forma é mais útil quando você não precisa ter acesso ao índice de cada iteração:

		<cfloop query="listagemData">
			<cfoutput>O usuário #nome# (de ID #id_usuario#), nasceu em #nascimento#;<br></cfoutput>
		</cfloop>
	

Aqui apenas utilizamos apenas o atributo query para fornecer a nossa query para o cfloop percorrê-la até o final;

Os campos da query, são convertidos automaticamente em variáveis dento do escopo do cfloop, e você pode acessá-los diretamente, como uma variável previamente instanciada;