Come posso utilizzare UNION query-of-query su n-recordset quando è necessario var scoping?
-
20-08-2019 - |
Domanda
Vorrei poter eseguire una query di una query su UNION un numero sconosciuto di recordset. Tuttavia, quando si eseguono query-of-query, i punti o le parentesi non sono consentiti nei nomi dei set di record.
Ad esempio questo non riesce:
<cfquery name="allRecs" dbtype="query">
SELECT * FROM recordset[1]
UNION
SELECT * FROM recordset[2]
</cfquery>
Utilizzo di nomi di variabili dinamiche come " recordset1 " funziona ma ha una funzione e deve essere var-scoped, quindi non posso costruire dinamicamente i nomi delle variabili senza produrre perdite di memoria in un oggetto persistente.
Altre idee?
Soluzione
Compito difficile. Potrei immaginare una soluzione con un ciclo nidificato basato su GetColumnNames()
, usando QueryAddRow()
e QuerySetCell()
. Non sarà il più efficiente, ma non è molto lento. Dipende dalle dimensioni dell'attività, ovviamente.
Il tuo " crea una funzione che combina due recordset " potrebbe essere reso molto più efficiente quando lo crei per accettare, diciamo, dieci argomenti. Modifica l'SQL al volo:
<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>
Altri suggerimenti
Dopo aver pubblicato la domanda, ho trovato un paio di soluzioni, ma potrebbe essercene una migliore là fuori
-
Potrei scrivere variabili denominate in modo dinamico nell'ambito degli argomenti e quindi fare riferimento a esse senza il loro ambito nella query
-
Crea una funzione che accetta 2 recordset come argomenti e restituisce un recordset combinato. Questo potrebbe essere ripetuto per aggiungere progressivamente un recordset alla volta. Sono sicuro che questo è molto inefficiente rispetto al fare tutte le UNION in una query però.
Dopo un breve giro in giro, ho trovato questo: queryConcat su CFLib.org. Utilizza queryaddrow / querysetcell per concatenare due query.
Ho aggiunto una funzione rapida (senza controllo degli errori o convalida dei dati, quindi non la userei così com'è):
<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>
Come test, ho messo insieme questo:
Il che, in effetti, ti dà fred / sammy / fred.
Probabilmente non è l'implementazione più efficiente, ma puoi sempre modificare il codice insert / union per renderlo più veloce se lo desideri. Principalmente, miravo a scrivere il minor codice possibile da solo. : -)
tutte le soluzioni aggiunte qui dovrebbero funzionare per te, ma vorrei anche menzionare che a seconda della quantità di dati con cui stai lavorando e del database che stai utilizzando, potresti essere meglio cercando di trovare un modo per farlo il lato del database. Con set di record molto grandi, potrebbe essere utile scrivere i record in una tabella temporanea e selezionarli di nuovo, ma in entrambi i casi, se è possibile in qualsiasi modo riscrivere le query per consentire al database di gestirlo in primo luogo meglio.