MYSQL高手进来,帮忙简化这个过程 本帖最后由 CHRL 于 2010-04-27 19:25:46 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你的SP要完成什么功能?SP有什么问题? 不好意恩,可能我还没有说清楚,这是一段用MYSQL写的bom查询的过程,我虽然已经实现了,但是整感觉是否可以再简化,因为在SQLSERVER里面只需要一个临时表,而在MYSQL里面因为无法一条SQL查询并且更新同一个临时表,所以出现以下要用到两个相同的临时表来处理,在这里问一下,有没有方法只需要一个临时表就可以处理这样的情况了?DELIMITER $$DROP PROCEDURE IF EXISTS `BOMTREE` $$CREATE DEFINER=`cessoftuser`@`%` PROCEDURE `BOMTREE`(`LJED1` VARCHAR(18))BEGINDECLARE CURLEVEL INT DEFAULT 0; /* 层级 */ SET @CURINDEX = 0;DROP TEMPORARY TABLE IF EXISTS `lelist1`;DROP TEMPORARY TABLE IF EXISTS `lelist2`;CREATE TEMPORARY TABLE `lelist1`( `BOMAED1` VARCHAR(18), /* 父件料号 */ `BOMITEM` INT, /* 序号 */ `BOMCED1` varchar(18), /* 子件料号 */ `BOMSTRUCTCODE` varchar(50), /* 主要用于排序 */ `BOMLEVEL` INT, /* 层级 */ PRIMARY KEY (`BOMSTRUCTCODE`)) ENGINE=MEMORY DEFAULT CHARSET=utf8;CREATE TEMPORARY TABLE `lelist2`( `BOMAED1` VARCHAR(18), `BOMITEM` INT, `BOMCED1` varchar(18), `BOMSTRUCTCODE` varchar(50), `BOMLEVEL` INT, PRIMARY KEY (`BOMSTRUCTCODE`)) ENGINE=MEMORY DEFAULT CHARSET=utf8;/* 第一步 插入第一层的物料 到 lelist1 *//* 第一步 复制 lelist1 到 lelist2 */INSERT INTO `lelist1`(BOMAED1,BOMITEM,BOMCED1,BOMSTRUCTCODE,BOMLEVEL)SELECT BOMAED1,@CURINDEX := @CURINDEX + 1,BOMCED1,LPAD(@CURINDEX,3,'000'),1FROM bommstr WHERE BOMAED1= LJED1 ORDER BY BOMAED1,BOMCED1;INSERT INTO `lelist2` SELECT * FROM `lelist1`;/* 一层一层插入记录到 lelist1 直到 18 层时退出 *//* 如果 lelist2 与 lelist1 有相同的记录就进行替换 */IF ROW_COUNT()>0 THEN LEVEL1: WHILE CURLEVEL <= 18 DO SET @CURINDEX = 0; REPLACE INTO `lelist1` (BOMAED1,BOMITEM,BOMCED1,BOMSTRUCTCODE,BOMLEVEL) SELECT ps_par, @CURINDEX := @CURINDEX + 1, BOMAED1, CONCAT(BOMSTRUCTCODE,LPAD(@CURINDEX,3,'000')), CURLEVEL FROM bommstr,`lelist2` WHERE ps_par = BOMCED1 and BOMIDAT='' ORDER BY ps_par,ps_comp; TRUNCATE TABLE `lelist2`; INSERT INTO `lelist2` SELECT * FROM `lelist1` WHERE BOMLEVEL=CURLEVEL; IF ROW_COUNT()=0 THEN LEAVE LEVEL1; END IF; SET CURLEVEL=CURLEVEL+1; END WHILE LEVEL1;END IF; 插入`lelist1`18次?用`lelist1`就行了,为什么要用`lelist2`? 不行的,因为 BOMMSTR 这个表里面的数据是一个树状的结构,我必须跟据 lelist1表里面的 BOMAED1 记录找bommstr表里对应的BOMCED1 一直找到树状表的叶子 如果是这样,就只有用两个临时表了,MYSQL不支持递归查询 BOMMSTR 表原始的数据----------------------------------------------BOMAED1 BOMCED1A A1A A2A A3A3 B1A3 B2B1 C1B2 D1B2 A1需要查询出来的数据BOMSTRUCTCODE BOMITEM BOMCED1 BOMLEVEL001 1 A1 3002 2 A2 1003 3 A3 1003001 1 B1 2003001001 1 C1 3003002 2 B2 2003002001 1 D1 3003002002 2 A1 3 明白了,你要递归插入数据,在MYSQL中,只有用SP+循环来解决,在SQLSERVER中可以用递归查询来解决 MySQL中进行树状所有子节点的查询 http://blog.csdn.net/ACMAIN_CHM/archive/2009/05/02/4142971.aspx 谢谢 ACMAIN_CHM 的帮忙,我已经成功改进了方法,效果很好,再次谢谢 mysql数据库如何备份? 求助连接池问题。 mysql连表查询 mysql数据库数问题,为什么数据库连接数会大于我设置的值 mysql语句问题 *** 高分请教:MySQL的问题,请注意不是SQLServer *** MySQL用C语言不能insert中文,请教该怎么解决?在线等,谢谢!谢谢! 在linux中安装mysql出现的问题,请高人指教 如何把查询结果中某个字段相同的结果只保留一条? mysql某个表中数据自己丢失 求助! 为什么运行时表的大小和实际物理文件大小差别会那么大 是否可以用一条SQL实现
CREATE DEFINER=`cessoftuser`@`%` PROCEDURE `BOMTREE`(`LJED1` VARCHAR(18))
BEGIN
DECLARE CURLEVEL INT DEFAULT 0; /* 层级 */
SET @CURINDEX = 0;
DROP TEMPORARY TABLE IF EXISTS `lelist1`;
DROP TEMPORARY TABLE IF EXISTS `lelist2`;CREATE TEMPORARY TABLE `lelist1`(
`BOMAED1` VARCHAR(18), /* 父件料号 */
`BOMITEM` INT, /* 序号 */
`BOMCED1` varchar(18), /* 子件料号 */
`BOMSTRUCTCODE` varchar(50), /* 主要用于排序 */
`BOMLEVEL` INT, /* 层级 */
PRIMARY KEY (`BOMSTRUCTCODE`))
ENGINE=MEMORY DEFAULT CHARSET=utf8;
CREATE TEMPORARY TABLE `lelist2`(
`BOMAED1` VARCHAR(18),
`BOMITEM` INT,
`BOMCED1` varchar(18),
`BOMSTRUCTCODE` varchar(50),
`BOMLEVEL` INT,
PRIMARY KEY (`BOMSTRUCTCODE`))
ENGINE=MEMORY DEFAULT CHARSET=utf8;/* 第一步 插入第一层的物料 到 lelist1 */
/* 第一步 复制 lelist1 到 lelist2 */
INSERT INTO `lelist1`(BOMAED1,BOMITEM,BOMCED1,BOMSTRUCTCODE,BOMLEVEL)
SELECT BOMAED1,@CURINDEX := @CURINDEX + 1,BOMCED1,LPAD(@CURINDEX,3,'000'),1
FROM bommstr WHERE BOMAED1= LJED1 ORDER BY BOMAED1,BOMCED1;INSERT INTO `lelist2` SELECT * FROM `lelist1`;/* 一层一层插入记录到 lelist1 直到 18 层时退出 */
/* 如果 lelist2 与 lelist1 有相同的记录就进行替换 */
IF ROW_COUNT()>0 THEN
LEVEL1: WHILE CURLEVEL <= 18 DO
SET @CURINDEX = 0;
REPLACE INTO `lelist1`
(BOMAED1,BOMITEM,BOMCED1,BOMSTRUCTCODE,BOMLEVEL)
SELECT ps_par,
@CURINDEX := @CURINDEX + 1,
BOMAED1,
CONCAT(BOMSTRUCTCODE,LPAD(@CURINDEX,3,'000')),
CURLEVEL
FROM bommstr,`lelist2`
WHERE ps_par = BOMCED1 and BOMIDAT=''
ORDER BY ps_par,ps_comp; TRUNCATE TABLE `lelist2`;
INSERT INTO `lelist2` SELECT * FROM `lelist1` WHERE BOMLEVEL=CURLEVEL; IF ROW_COUNT()=0 THEN LEAVE LEVEL1; END IF;
SET CURLEVEL=CURLEVEL+1;
END WHILE LEVEL1;
END IF;
用`lelist1`就行了,为什么要用`lelist2`?
BOMMSTR 表原始的数据
----------------------------------------------
BOMAED1 BOMCED1
A A1
A A2
A A3
A3 B1
A3 B2
B1 C1
B2 D1
B2 A1需要查询出来的数据
BOMSTRUCTCODE BOMITEM BOMCED1 BOMLEVEL
001 1 A1 3
002 2 A2 1
003 3 A3 1
003001 1 B1 2
003001001 1 C1 3
003002 2 B2 2
003002001 1 D1 3
003002002 2 A1 3
在SQLSERVER中可以用递归查询来解决
http://blog.csdn.net/ACMAIN_CHM/archive/2009/05/02/4142971.aspx