質問

次の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行すべてを持つクエリオブジェクトが必要です。どうすればこれを達成できますか?

役に立ちましたか?

解決

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

クエリのクエリで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>

他のヒント

より直接的な方法は次のようなものかもしれません:

<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()割り当てが必要です。をチェックしてください ライブドキュメントのクエリ機能 詳細については。

以下は、SQLビューの保存されたプロックを放棄して、箱のないソリューションです(説明します)。

免責事項:SPソースコードを表示せずに、ソリューションが適合するかどうかわかりません。私はSPがかなり基本的であると仮定しており、私は通常、ビューよりもSPのコンパイルされた実行を好むことを認めていますが、SQLビューの1回限りの実行はSP X時間のループを上回るはずです。

最初に、SPの選択ステートメントのように見えるビューを作成します(もちろん、パラメーター化を除いて - 新しいビューのcfquery内の句でそれをカバーします。

次に、ループを設定して、Where句に使用するデータセットを構築する以外に実行します。 ArrayTolistと少しの文字列操作を使用して、最終製品がこのように見える単一のCF変数に格納されている文字列であるため、次のようになります。

( 'valueofarrayelement1'、 'valueofarrayelement2'、 'value_and_so_on')

文字列の構築は、ArrayTolistのデリメーター属性を使用して非常に簡単で、ループが完了した後、左の括弧と単一の引用を左の最も位置に追加します。文字列内の正しい位置に単一の引用と右括弧を追加します。

次に、cfqueryステートメントを記述して、[SPを実行する代わりに)ビューから必要な列を選択します。そして、パラメーターをSPに渡す代わりに、CFQueryにWhere句を置くことになります。

ああ、ところで、私はあなたがSQLビューが必要だと述べていますが、全体は選択されています たぶん......だろう cfqueryに組み込まれます。個人的には、マルチテーブル結合があるとき、それをCFQueryでの結合よりも迅速に実行されるSQLビューで定義するのが好きです。最終的には、StoredProcはさらに高速ですが、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ビューの保存されたプロックを放棄するのはちょっと奇妙ですが、私たちはより大きなパフォーマンスを達成すると確信しており、それもかなり読みやすいと思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top