我正在尝试将Coldfusion的产品搜索转移到MySQL存储过程中。
搜索有大约20个标准,并且是它所在站点的一个vanilla-function,所以想将它转换为存储过程,因为需要进行大量的预编译。
我想我找出了大部分的搜索标准。我正在努力争取最后一个。
首先是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中创建第二部分,即循环通过临时表的结果并从中构造上述语句?
我还是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
我迷路了......
答案 0 :(得分:0)
替换SELECT sid, pricelist
使用SELECT sid, ifnull(pricelist,'BASE')
(sql server readers,mysql的ifnull()
就像你的isnull()
函数一样)
这使得价格表在null时显示为“BASE”。
然后,您可以跳过<cfif pricelist IS ''>
+ <cfelse>
如果您使用的是cf9 +,您还可以使用速记连接<cfset misterLister &= "value">
通过构建动态sql并执行内部存储过程,您将获得更好的性能。 减少数据库往返次数。如果coldfusion只需要与mysql交谈一次就会更快。
您不需要临时表来循环。只需构建sql字符串即可直接在查询中执行。然后执行sql string。
不要担心游标 - 它们适用于您想要加载某些记录,循环它们并在每一行上执行操作。
准备好的陈述: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
您基本上需要一个提供参数的存储过程。它在内部构建一个准备和执行的字符串。返回结果数据。