Как я могу использовать объединение запроса к запросу для n-наборов записей, когда требуется определение области видимости var?

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

  •  20-08-2019
  •  | 
  •  

Вопрос

Я хотел бы иметь возможность выполнить запрос запроса для ОБЪЕДИНЕНИЯ неизвестного количества наборов записей.Однако при выполнении запроса из запроса точки или скобки не допускаются в именах наборов записей.

Например, это не удается:

<cfquery name="allRecs" dbtype="query">
    SELECT * FROM recordset[1]
    UNION
    SELECT * FROM recordset[2]
</cfquery>

Использование динамических имен переменных, таких как "recordset1", работает, но это в функции и должно быть ограничено переменными, поэтому я не могу динамически создавать имена переменных без возникновения утечек памяти в сохраняемом объекте.

Есть еще какие-нибудь идеи?

Это было полезно?

Решение

Трудная задача.Я мог бы представить себе решение с вложенным циклом, основанным на GetColumnNames(), используя QueryAddRow() и QuerySetCell().Это будет не самый эффективный способ, но на самом деле он не медленный.Конечно, зависит от размера задачи.

Ваше "создать функцию, которая объединяет два набора записей" можно было бы сделать намного эффективнее, если бы вы создали ее для приема, скажем, десяти аргументов.Модифицируйте SQL на лету:

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

Другие советы

После публикации вопроса я придумал пару решений, но, возможно, есть что-то получше

  • Я мог бы записать динамически именованные переменные в область аргументов, а затем ссылаться на них без их области в запросе

  • Создайте функцию, которая принимает 2 набора записей в качестве аргументов и возвращает один объединенный набор записей.Это можно было бы зациклить, чтобы постепенно добавлять набор записей за раз.Я уверен, что это очень неэффективно по сравнению с выполнением всех объединений в одном запросе, хотя.

После недолгих поисков я нашел это:queryConcat - Запрос в CFLib.org.Он использует queryaddrow /querysetcell для объединения двух запросов.

Я добавил быструю функцию (без проверки ошибок или проверки данных, поэтому я бы не стал использовать ее как есть).:

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

В качестве теста я собрал это вместе:

Что, по сути, дает вам фреда / Сэмми / fred.

Вероятно, это не самая эффективная реализация, но вы всегда можете изменить код вставки / объединения, чтобы сделать его быстрее, если захотите.В основном, я стремился написать как можно меньше кода самостоятельно.:-)

все добавленные здесь решения должны работать для вас, но я бы также упомянул, что в зависимости от объема данных, с которыми вы работаете, и используемой базы данных вам, возможно, лучше попытаться найти способ сделать это на стороне базы данных.При очень больших наборах записей может быть полезно записать записи во временную таблицу и снова выделить их, но в любом случае, если вы можете каким-либо образом переписать запросы, чтобы база данных обрабатывала это в первую очередь, вам будет лучше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top