coldfusion - ¿Cómo puedo usar UNION de query-of-query en n-recordsets cuando se necesita var scoping?
cfquery qoq (4)
Después de hurgar un poco, encontré esto: queryConcat en CFLib.org. Utiliza queryaddrow / querysetcell para concatenar dos consultas.
Agregué una función rápida (sin comprobación de errores ni validación de datos, así que no la usaría como está):
<cffunction name="concatenate">
<cfset var result = arguments[1]>
<cfloop from="2" to="#arraylen(arguments)#" index="i">
<cfset result=queryconcat(result, arguments[i])>
</cfloop>
<cfreturn result>
</cffunction>
Como prueba, arrojé esto juntos:
Lo cual, de hecho, te da fred / sammy / fred.
Probablemente no sea la implementación más eficiente, pero siempre puede modificar el código de inserción / unión para hacerlo más rápido si así lo desea. En su mayoría, tenía el objetivo de escribir el menor código posible por mi cuenta. :-)
Me gustaría poder hacer una consulta de una consulta a UNION con un número desconocido de recordset. Sin embargo, al hacer una consulta de consulta, los puntos o corchetes no están permitidos en los nombres de los conjuntos de registros.
Por ejemplo, esto falla:
<cfquery name="allRecs" dbtype="query">
SELECT * FROM recordset[1]
UNION
SELECT * FROM recordset[2]
</cfquery>
Usar nombres dinámicos de variables como el trabajo "recordset1" pero esto está en una función y necesita ser var-scoped para que no pueda construir dinámicamente los nombres de las variables sin producir pérdidas de memoria en un objeto persistente.
¿Alguna otra idea?
Después de publicar la pregunta, se me ocurrió un par de soluciones, pero podría haber una mejor por ahí
Podría escribir dinámicamente las variables con nombre en el alcance de los argumentos y luego hacer referencia a ellos sin su alcance en la consulta
Cree una función que acepte 2 conjuntos de registros como argumentos y devuelva un conjunto de registros combinados. Esto podría buclearse para agregar progresivamente un conjunto de registros a la vez. Estoy seguro de que esto es muy ineficiente en comparación con hacer todas las UNIONES en una sola consulta.
Tarea difícil. Podría imaginar una solución con un ciclo anidado basado en GetColumnNames()
, usando QueryAddRow()
y QuerySetCell()
. No será el más eficiente, pero no es realmente lento. Depende del tamaño de la tarea, por supuesto.
Su "creación de una función que combina dos conjuntos de registros" podría hacerse mucho más eficiente cuando la cree para aceptar, digamos, diez argumentos. Modificar el SQL sobre la marcha:
<cfset var local = StructNew()>
<cfquery name="local.union" dbtype="query">
SELECT * FROM argument1
<cfloop from="2" to="#ArrayLen(arguments)#" index="local.i">
<cfif IsQuery(arguments[local.i])>
UNION
SELECT * FROM argument#local.i#
</cfif>
</cfloop>
</cfquery>
<cfreturn local.union>
Todas las soluciones agregadas aquí deberían funcionar para usted, pero también mencionaría que, dependiendo de la cantidad de datos con los que esté trabajando y la base de datos que esté utilizando, es mejor que intente encontrar la forma de hacerlo en el lado de la base de datos. . Con conjuntos de registros muy grandes, puede ser beneficioso escribir los registros en una tabla temporal y seleccionarlos de nuevo, pero de cualquier manera, si de alguna manera puede reescribir las consultas para permitir que la base de datos maneje esto en primer lugar, estará Mejor sin.