0

製品検索を Coldfusion から MySQL ストアド プロシージャに移動しようとしています。

検索には約 20 の基準があり、それが含まれているサイトのバニラ関数であるため、プリコンパイルを行う必要があるため、ストアド プロシージャに変換したいと考えていました。

ほとんどの検索条件を把握できたと思います。ラストで悩んでいます。

まず、Coldfusion の部分:

<cfquery datasource="dtb" name="get_pricelists">
  SELECT sid, pricelist
  FROM buyerList AS b
  LEFT JOIN sellerList AS s ON s.sid = b.sid AND s.pass = b.pass
  WHERE b.bid = >parameter<
</cfquery>

これにより、価格表と現在のユーザーのそれぞれの価格表を使用して、すべての販売者が選択されます。次のようになります (MySQL では一時テーブルを作成しています):

=====================
sellerID    pricelist
12345         NULL
23467         foo
99999         bar

次の部分は私が苦労しているところです:

<cfset misterLister = "LEFT JOIN preislisten p ON ">
<cfoutput query="get_pricelists" >
<cfif pricelist IS ''>
     <cfset misterLister = misterLister & '(p.sid = a.sid AND p.pricelist = "BASE" AND p.ean = a.ean AND p.iln = "#sellerID#") OR '>
  <cfelse>
     <cfset misterLister = misterLister & '(p.sid = a.sid AND p.pricelist = "#pricelist#" AND p.ean = a.ean AND p.iln = "#sellerID#") OR '>
  </cfif>
</cfoutput>
<cfset misterLister = misterLister & "(1=0)">

したがって、上記の例では、見つかった 3 つの販売者と価格表をループして、Coldfusion でこの MySQL 構文を作成します。

LEFT JOIN pricelists p ON
   (p.sid = a.sid AND p.pricelist = "BASE" AND p.ean = a.ean AND p.iln = 12345 ) OR 
   (p.sid = a.sid AND p.pricelist = "foo" AND p.ean = a.ean AND p.iln = 23467 ) OR 
   (p.sid = a.sid AND p.pricelist = "bar" AND p.ean = a.ean AND p.iln = 99999) OR 
   (1=0)

これは実際のクエリに渡されます。

質問:
最初の部分を実行して一時テーブルに保存できます。しかし、MySQL で 2 番目の部分を作成することもできますか?つまり、一時テーブルの結果をループして、そこから上記のステートメントを作成することはできますか?

私はまだ MySQL の初心者なので、どこから始めればよいかわかりません。準備済みステートメントとカーソルを見ていますが、これらは唯一のオプションですか?

編集:
わかりました。私は最初の準備されたステートメントを考え出そうとしました。次のようになります。

SET @sql_text := '
DECLARE strCount   INT DEFAULT 1;

SELECT sid, ifnull(pricelist,"BASE"), count(*) AS recs
    FROM buyerList AS b
    LEFT JOIN sellerList AS s ON s.sid = b.sid AND s.pass = b.pass
    WHERE b.bid = ?

SET @string = "LEFT JOIN preislisten AS p";

lj:
  LOOP

    SET @string = CONCAT( @string, "ON (p.iln = a.iln AND p.preisliste = sid AND p.ean = a.ean AND p.iln = pricelist ) OR");

    SET strCount = strCount+1;
    IF strCount = recs
    THEN LEAVE lj;
    END IF;

END LOOP lj;

SET @string = CONCAT( @string,"(1=0)")
';
SET @param_iln = param_iln;
PREPARE stmt FROM @sql_text;
EXECUTE stmt using @param_iln;
DEALLOCATE PREPARE stmt;

したがって、prep ステートメント文字列内で最初のクエリを実行し、見つかった価格表をループできるようにしたいと考えています (売り手と価格表が 3 つ以上になるため、ループを実行する必要がありますよね?)。すべてを連結します。しかし、これが機能する場合、この文字列を実際の検索クエリに追加するにはどうすればよいでしょうか。これは次のようになります。

SELECT articles AS art 
   << insert left join here >>
    FROM bigtable AS bt
    WHERE
      a lot of other criteria

道に迷いました...

4

1 に答える 1

0

交換SELECT sid, pricelist

SELECT sid, ifnull(pricelist,'BASE')

(SQL サーバー リーダー、mysqlifnull()は関数のようなものisnull()です)

これにより、null の場合に価格表が「BASE」として出力されます。

<cfif pricelist IS ''>その後、 +をスキップできます<cfelse>

cf9+ を使用している場合は、短縮形の連結も使用できます<cfset misterLister &= "value">

動的 sql を構築し、ストアド プロシージャ内で実行することにより、パフォーマンスが向上します。データベースの往復が少なくなります。coldfusion が mysql と通信する必要があるのは 1 回だけであれば、より高速です。

ループする一時テーブルは必要ありません。クエリで直接実行する SQL 文字列を作成するだけです。次に、SQL 文字列を実行します。

カーソルについて心配する必要はありません。カーソルは、いくつかのレコードをロードし、それらをループして、各行でアクションを実行するためのものです。

準備済みステートメント: http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-prepared-statements.html

ストアド プロシージャ: http://dev.mysql.com/doc/refman/5.1/en/create-procedure.html

基本的に、引数を指定するストアド プロシージャが必要です。準備され実行される文字列を内部的に構築します。結果のデータを返します。

于 2012-06-21T13:52:18.993 に答える