Boas pessoal!
O Coldfusion tem um recurso muito útil conhecido como “Query of Queries” ( QoQ ) que permite você fazer uma query em um resultado de outra query sem a necessidade de acessar o banco de dados ( ou outra fonte ) novamente.
Os 3 principais servidores Coldfusion suportam QoQ e para maiores detalhes veja a documentação do ACF - Adobe ColdFusion, do Railo ou do Lucee.

A ideia neste post é registrar um exemplo de como utilizar QoQ totalmente em CFScript, já que é amplamente recomendado usar CFScript em componentes CFC no lugar de tags.

Dada a classe MyClass.cfc abaixo, temos uma lista de linguagens de programação (que poderia ter vindo de qualquer fonte de dados, como um arquivo Excel por exemplo) e queremos que nosso método getLanguages() retorne esta lista em ordem alfabética.

component output="false" displayname="MyClass"  {

public function init(){
return this;
}

public function getLanguages() {
local.result = "";
local.qLang = queryNew("id,name", "Integer,Varchar",
[
{id=1,name="CFML"},
{id=2,name="Ruby"},
{id=3,name="Python"},
{id=4,name="Perl"},
{id=5,name="Java"}
]
);

local.qoq = new Query();

local.qoq.setAttributes( originalResult = local.qLang,
DBType="query",
Name="exampleQuery"
);

local.result = local.qoq.execute( sql = "SELECT * FROM originalResult ORDER BY name").getResult();

return local.result;
}
}

Vamos destrinchá-lo!


    local.qoq = new Query();

Criamos um novo objeto Query chamado qoq, que futuramente executará a consulta na query de origem que chamamos de qLang.


    local.qoq.setAttributes(  originalResult = local.qLang,
                              DBType="query",
                              Name="exampleQuery"
                            );

Em seguida, atribuímos algumas propriedades para esta nova query.

O grande facilitador aqui é a propriedade originalResult, que poderia se chamar qualquer outra coisa. Nela atribuímos o resultSet da query original ( qLang ) que será utilizada no FROM da nossa query final.

A propriedade DBType indica que esta query irá consultar uma outra query ( e não o banco de dados ).

A propriedade Name já é mais conhecida. É o nome da query e ajuda muito quando estamos debugando.


    local.result = local.qoq.execute( sql = "SELECT * FROM originalResult ORDER BY name").getResult();

Acima executamos a query com o sql que precisamos e atribuímos o seu resultado para a variável result.

Repare que no FROM desta query utilizamos originalResult, que nada mais é que a propriedade que criamos com o setAttributes e populamos com o resultSet da query original ( qLang ).

Por fim, basta retornar o valor da variável result.

Neste exemplo, utilizamos um simples “order by, mas, o céu é o limite!

O código fonte completo deste exemplo está no meu Github.

E você, como utiliza os poderes da Query of Query? Gostaria de acrescentar, corrigir ou sugerir algo? Comente a vontade!

PS: Este código foi testado no ACF 10.

Gde. abraço!

Ed