fre*_*ent 7 mysql stored-procedures prepared-statement
我在 MySQL 中运行搜索查询以从产品和价目表表中返回项目。当用户进行搜索查询时,我需要从产品表中获取产品 LEFT JOINED 与来自第二个表(任意数量的卖家)的所有授权/解锁卖家。
我有基本的搜索查询工作,但我无法让“动态左联接”工作。我在准备声明中被告知要这样做,我(a)正在努力(第一次)并且我不知道在工作时把它放在哪里。
我的搜索查询将如下所示:
SELECT articles AS art
<< need to left join here >>
FROM bigtable AS bt
WHERE
a lot of other criteria
Run Code Online (Sandbox Code Playgroud)
这是我想出的准备声明:
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;
Run Code Online (Sandbox Code Playgroud)
所以我基本上是找到所有卖家和价格表名称(默认 BASE),然后尝试构造一个这样的字符串:
LEFT JOIN pricelists p ON
(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)
Run Code Online (Sandbox Code Playgroud)
我的问题:
(1) 如果有 25 个卖家,我会做 25 个循环,但是正确的卖家和价目表会像这样插入到我的字符串中吗?
(2) 如何将其插入到我的实际搜索查询中?如果我执行,我可能会得到一个字符串,但我不能只将字符串放入查询中,对吗?
感谢您对我的宽容...第一次准备声明,第 2 周 MySQL...
编辑:
所以这就是我想出的:
# bigtable query
SELECT count(a.id) AS gesamt_datensaetze, a.nos, a.nos_anzeige
FROM artikelstammdaten AS a
#JOIN colors
LEFT JOIN farbenzuordnung AS zu
ON a.farbe = zu.farbe
AND ( ( param_filter = '' ) AND (1=1) OR ( zu.ILN = param_filter ) )
# ========== NEW PART ==========
LEFT JOIN preislisten AS p
ON ( p.iln = a.iln
AND p.EAN = a.EAN
AND p.preisliste = ( #NEW GET pricelists
SELECT IFNULL(klhs.preisliste, "-Standard-") AS pricelistID
FROM kundenliste_haendler AS klhd
LEFT JOIN kundenliste_hersteller AS klhs
ON klhs.iln = klhd.iln_verkaeufer
AND klhs.plz = klhd.plz
AND klhs.cid= klhd.cid
WHERE klhd.iln_kaeufer = param_iln
GROUP BY pricelistID
)
AND p.iln = ( #GET seller
SELECT klhd.iln_verkaeufer AS sellerID
FROM kundenliste_haendler AS klhd
LEFT JOIN kundenliste_hersteller AS klhs
ON klhs.iln = klhd.iln_verkaeufer
AND klhs.plz = klhd.plz
AND klhs.cid= klhd.cid
WHERE klhd.iln_kaeufer = param_iln
GROUP BY pricelistID
)
)
# active
WHERE a.aktiv = "ja"
# more criteria
Run Code Online (Sandbox Code Playgroud)
仍然试图找出这是否正常工作。如果有人可以对我是否可以将我的(相同的)嵌套选择合并为一个嵌套选择有一些见解,将不胜感激!
从问题来看,您编写的内容与 Oracle 所谓的匿名代码块类似。MySQL 不支持这种机制。
至于你想完成什么,你不需要存储过程。
尝试像这样组装 SQL 语句:
@stmt = 'SELECT sid, ifnull(pricelist,"BASE"), count(*) AS recs FROM buyerList AS b ';
@stmt = CONCAT(@stmt,'LEFT JOIN sellerList AS s ON s.sid = b.sid AND s.pass = b.pass ');
@stmt = CONCAT(@stmt,'LEFT JOIN pricelists p ON ');
SELECT GROUP_CONCAT(CONCAT('(p.sid = a.sid AND p.preisliste = ',sid,' AND p.ean = a.ean AND p.iln = ',pricelist',)') SEPARATOR ' OR ')
INTO @LeftJoinClause FROM preislisten;
@stmt = CONCAT(@stmt,@LeftJoinClause,' WHERE b.bid = ?');
SELECT @stmt\G
Run Code Online (Sandbox Code Playgroud)
这将打印出所需的查询
如果它是所需的查询,则执行它
PREPARE sql FROM @stmt;
EXECUTE sql using @param_iln;
DEALLOCATE PREPARE sql;
Run Code Online (Sandbox Code Playgroud)
试一试 !!!
如果您确实希望查询很小而不对每个值进行硬编码,只需使用更直接的 LEFT JOIN 设置编写代码
SELECT p.sid, ifnull(p.pricelist,"BASE"), count(*) AS recs FROM buyerList AS b
LEFT JOIN sellerList AS s ON s.sid = b.sid AND s.pass = b.pass
LEFT JOIN pricelists p ON
(p.sid = a.sid AND p.preisliste = a.sid AND p.ean = a.ean)
WHERE b.bid = ?
GROUP BY p.sid,p.pricelist;
Run Code Online (Sandbox Code Playgroud)
我也刚刚注意到你有 a.sid 和 a.ean,哪个表的别名是a
?
关注在 SELECTS 内运行存储过程的技术问题,不。
我创建了一个测试来证明内联 SQL 和存储过程的上下文是不同的:
mysql> delimiter $$
mysql> CREATE PROCEDURE test123 ()
-> begin
-> SELECT NOW();
-> end;
-> $$
Query OK, 0 rows affected (1.04 sec)
mysql> delimiter ;
mysql> call test123();
+---------------------+
| NOW() |
+---------------------+
| 2012-06-21 08:58:15 |
+---------------------+
1 row in set (0.04 sec)
Query OK, 0 rows affected (0.04 sec)
mysql> SELECT t.* FROM ( call test123() ) t;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'call test123() ) t' at line 1
mysql> SELECT ( call test123() ) AS t;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'call test123() ) AS t' at line 1
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
32487 次 |
最近记录: |