2

次の ColdFusion 9 コードがあります。

<cfloop from="1" to="#arrayLen(tagArray)#" index="i">
    <cfquery name="qryGetSPFAQs" datasource="#application.datasource#">
        EXEC searchFAQ '#tagArray[i]#'
    </cfquery>
</cfloop>

EXEC はデータベース サーバー上でストアド プロシージャを実行し、パラメータの内容に応じてデータの行を返します。私がやろうとしているのは、クエリを 1 つのクエリ オブジェクトに結合することです。つまり、3 回ループし、各ループが 4 行を返す場合、1 つのオブジェクトに 12 行すべてを含むクエリ オブジェクトが必要です。どうすればこれを達成できますか?

4

3 に答える 3

2

別のアプローチ (ストアド プロシージャを変更して複数の引数を受け入れるか、リストとfnSplitを使用する) を取り、データセットを一度に返すことをお勧めします。ただし、質問に直接答えるには、次のようにクエリを組み合わせることができます。

Query of Queries で UNION を使用して、すべてのデータセットを組み合わせることができます。

<cfloop from="1" to="#arrayLen(tagArray)#" index="i">
    <cfquery name="qryGetSPFAQs#i#" datasource="#application.datasource#">
        EXEC searchFAQ '#tagArray[i]#'
    </cfquery>
</cfloop>

<cfquery name="combined" dbtype="query">
    <cfloop from="1" to="#arrayLen(tagArray)#" index="i">
        select * from qryGetSPFAQs#i#
        <cfif i lt arrayLen(tagArray)>UNION</cfif>
    </cfloop>
</cfquery>
于 2010-05-28T21:09:20.390 に答える
1

より直接的な方法は、次のようなものです。

<cfset bigQ = queryNew("column")>
<cfloop from="1" to="#arrayLen(tagArray)#" index="i">
    <cfquery name="qryGetSPFAQs" datasource="#application.datasource#">
        EXEC searchFAQ '#tagArray[i]#'
    </cfquery>
    <cfset queryAddRow(bigQ)>
    <cfset querySetCell(bigQ, "column". qryGetSPFAQs)>
</cfloop>

列ごとに querySetCell() の割り当てが必要になります。詳細については、ライブ ドキュメントのクエリ関数を確認してください。

于 2010-05-28T23:37:13.810 に答える
0

これは、SQL ビューの StoredProc を放棄した、すぐに使用できるソリューションです (後で説明します)。

免責事項: SP のソース コードを見ないと、私のソリューションが適切かどうかわかりません。私は SP がかなり基本的なものであると想定しています。私は通常、ビューよりも SP のコンパイル済み実行を好むことを認めますが、SQL ビューの 1 回の実行は、SP の x 回のループよりも優れているはずです。

最初に、SP の SELECT ステートメントに似たビューを作成します (もちろん、パラメーター化は除きます。これは、新しいビューの CFQUERY 内の WHERE 句でカバーします。

次に、WHERE 句に使用するデータ セットを構築するだけのループを設定します。ArrayToList と少しの文字列操作を使用して整理する必要があります。最終製品は、次のように単一の CF 変数に格納された文字列です。

('ValueOfArrayElement1','ValueOfArrayElement2','Value_And_So_On')

ArrayToList の区切り属性を使用して文字列を作成するのは非常に簡単です。ループが完了したら、左括弧と一重引用符を文字列の一番左の位置に追加します。文字列の一番右の位置に一重引用符と右括弧を追加します。

ここで、(SP を実行する代わりに) ビューから必要な列を選択する CFQUERY ステートメントを記述します。SP にパラメーターを渡す代わりに、CFQUERY に WHERE 句を挿入します。

ところで、SQL ビューが必要だと言っていますが、SELECT 全体を CFQUERY で構築できます。個人的には、複数テーブルの JOIN がある場合、CFQUERY での JOIN よりも高速に実行される SQL ビューでそれを定義するのが好きです。最終的に StoredProc はさらに高速ですが、WHERE 句は、SQL をループインおよびループアウトせずに StoredProc に送信するよりも、このようにコーディングして読みやすくなっています。

可能であれば、データベースへの往復を 1 回だけにすることをお勧めします。そのため、配列をループして、データセット内のすべての値に相当する文字列を書き込みました。このようにして、一度に 1 つのクエリのみを実行します。

SELECT Col1, Col2, Col_etc
FROM SQL_View_Name
WHERE ColumnName in #BigStringWeMadeFromArrayToList#

CFQUERY がレンダリングされると、句は SQL で次のようになります。

WHERE ColumnName in 
     ('ValueOfArrayElement1','ValueOfArrayElement2','Value_And_So_On')

それで、あなたはそれを持っています。私が言ったように、これは DB へのアクセスが 1 回だけなので便利です。また、ビューを構築しているので、StoredProc を 4 回以上実行するよりも優れたパフォーマンスを維持できます。(悪気はない)

繰り返す必要があります... SPコードを見たことがないため、これが実行可能かどうかわかりません。さらに、RDBMS の「下位」エンティティである SQL ビューの StoredProc を放棄するのはちょっと奇妙ですが、より優れたパフォーマンスを達成できると確信しており、かなり読みやすいと思います。

于 2010-09-25T04:31:48.173 に答える