0

我正在尝试将产品搜索从 Coldfusion 转移到 MySQL 存储过程中。

搜索有大约 20 个标准,并且是它所在站点的普通功能,因此希望将其转换为存储过程,因为必须进行大量预编译。

我想我找出了大部分的搜索条件。我正在努力解决最后一个问题。

首先是冷融合部分:

<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 中创建第二部分,即遍历临时表的结果并从中构造上述语句?

我还是 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 server 读者,mysql 的ifnull()就像你的isnull()函数)

这使得价格表在为空时显示为“BASE”。

然后,您可以跳过<cfif pricelist IS ''>+<cfelse>

如果您使用的是 cf9+,您还可以使用速记连接<cfset misterLister &= "value">

通过构建动态 sql 并在存储过程中执行,您将获得更好的性能。更少的数据库往返。如果coldfusion 只需要和mysql 对话一次会更快。

你不需要一个临时表来循环。只需构建 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 回答