Come posso utilizzare UNION query-of-query su n-recordset quando è necessario var scoping?

StackOverflow https://stackoverflow.com/questions/485212

  •  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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top