5

我希望能够对 UNION 未知数量的记录集进行查询。但是,在进行查询查询时,记录集名称中不允许使用点或括号。

例如,这失败了:

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

使用诸如“recordset1”之类的动态变量名可以工作,但这是在一个函数中并且需要在 var 范围内,所以我不能动态地建立变量名而不在持久对象中产生内存泄漏。

还有其他想法吗?

4

4 回答 4

2

发布问题后,我想出了几个解决方案,但可能会有更好的解决方案

  • 我可以将动态命名的变量写入参数范围,然后在没有查询范围的情况下引用它们

  • 创建一个接受 2 个记录集作为参数并返回一个组合记录集的函数。这可以循环以逐步添加一个记录集。不过,与在一个查询中执行所有 UNION 相比,我确信这非常低效。

于 2009-01-27T21:08:59.013 回答
1

困难的任务。我可以想象一个基于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>
于 2009-01-27T21:46:16.630 回答
1

在快速浏览了一下之后,我发现了这个: CFLib.org上的 queryConcat。它使用 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/sammy/fred。

这可能不是最有效的实现,但如果需要,您可以随时更改插入/联合代码以使其更快。大多数情况下,我的目标是自己编写尽可能少的代码。:-)

于 2009-01-27T22:31:46.070 回答
1

这里添加的所有解决方案都应该适合您,但我还要提到,根据您使用的数据量和您使用的数据库,您最好尝试在数据库端找到一种方法来执行此操作. 对于非常大的记录集,将记录写入临时表并再次选择它们可能是有益的,但无论哪种方式,如果您可以以任何方式重写查询以让数据库首先处理这个问题,您将过得更好。

于 2009-02-03T14:08:24.423 回答