MySQL中关于行转列的存储过程的写法(使用游标)

本文深入解析了MySQL存储过程`sp_pro_rm_cs`的实现细节,包括其结构、参数使用及核心逻辑。通过具体代码实例,详细阐述了如何构建并执行该存储过程,以实现特定业务需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
-- ----------------------------
-- Procedure structure for `sp_pro_rm_cs`
-- ----------------------------
DROP PROCEDURE IF EXISTS `sp_pro_rm_cs`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_pro_rm_cs`(in p_bookno varchar(64))
BEGIN
	DECLARE v_sql VARCHAR(8000);
	DECLARE v_rmname VARCHAR(20);
	DECLARE v_rmcode VARCHAR(20);
	DECLARE v_row INT(11);
	DECLARE v_done INT(11);
	DECLARE v_i INT(11);

	DECLARE csr_rm CURSOR FOR
		SELECT DISTINCT pr_rmname, pr_rmcode FROM v_pro_rm_cs_info WHERE pr_bookno = p_bookno;
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = 1;

	DROP TABLE IF EXISTS v_pro_rm_cs_info;
	CREATE TEMPORARY TABLE v_pro_rm_cs_info (
		pr_bookno varchar(20) DEFAULT NULL,
		pr_rmname varchar(20) DEFAULT NULL,
		pr_rmcode varchar(20) DEFAULT NULL,
		pr_pname  varchar(20) DEFAULT NULL,
		pr_rmloss decimal(10,3) DEFAULT NULL,
		pr_rmrate decimal(10,3) DEFAULT NULL
	);

	INSERT INTO v_pro_rm_cs_info (pr_bookno, pr_rmname, pr_rmcode, pr_pname, pr_rmloss, pr_rmrate)
	SELECT t1.rb_book_no AS pr_bookno, t1.rb_rm_name AS pr_rmname, t1.rb_rm_code AS pr_rmcode, 
				 t2.cs_pname AS pr_pname, t2.cs_loss AS pr_rmloss, t2.cs_rate AS pr_rmrate
	FROM t_rm_backup t1 LEFT JOIN m_consumption t2 ON t1.rb_rm_name = t2.cs_rmname AND t1.rb_rm_code = t2.cs_rmcode;

	SET v_done = 0;
	SET v_sql = 'select distinct t1.pr_pname, t2.pl_pwgt_sum AS pr_pwgt_s';

	SET v_i = 1;
	OPEN csr_rm;
	csr_loop:loop
		FETCH csr_rm INTO v_rmname, v_rmcode;
		IF v_done THEN
			LEAVE csr_loop;
		END IF;
			SET v_sql = concat(v_sql, ', sum(case when t1.pr_rmname = "', v_rmname, '" and t1.pr_rmcode = "', v_rmcode,'" then t1.pr_rmloss else null end) "', 'pr_', v_i, 'l"');
			SET v_sql = concat(v_sql, ', sum(case when t1.pr_rmname = "', v_rmname, '" and t1.pr_rmcode = "', v_rmcode,'" then t1.pr_rmrate else null end) "', 'pr_', v_i, 'r"');

			SET v_sql = concat(v_sql, ', sum(case when t1.pr_rmname = "', v_rmname, '" and t1.pr_rmcode = "', v_rmcode,'" then Round(t2.pl_pwgt_sum * t1.pr_rmloss, 2) else null end) "', 'pr_', v_i, 'rl"');
			SET v_sql = concat(v_sql, ', sum(case when t1.pr_rmname = "', v_rmname, '" and t1.pr_rmcode = "', v_rmcode,'" then Round((t2.pl_pwgt_sum * t1.pr_rmloss * t1.pr_rmrate) / (1 - t1.pr_rmrate), 2) else null end) "', 'pr_', v_i, 'rr"');

			SET v_i = v_i + 1;
	END LOOP;

	CLOSE csr_rm;

	SET v_sql = concat(v_sql, ' from v_pro_rm_cs_info t1 ');

	SET v_sql = concat(v_sql, ' left join ( ');
	SET v_sql = concat(v_sql, ' 	select distinct t3.pl_pname, SUM(t3.pl_pwgt_sum) as pl_pwgt_sum, t4.mb_bookno ');
	SET v_sql = concat(v_sql, ' 	from t_packlist t3 inner join t_manual_book t4 ');
	SET v_sql = concat(v_sql, ' 	on t3.pl_ex_date >= t4.mb_wo_stt and t3.pl_ex_date <= t4.mb_wo_end ');
	SET v_sql = concat(v_sql, ' 	group by pl_pname ');
	SET v_sql = concat(v_sql, ' ) t2 on t1.pr_bookno = t2.mb_bookno and t1.pr_pname = t2.pl_pname ');

	SET v_sql = concat(v_sql, ' group by t1.pr_pname ');

	SET @sql = v_sql;


  PREPARE sl FROM @sql;
  EXECUTE sl;
  DEALLOCATE PREPARE sl;
/*
	SELECT @sql;
*/
END
;;
DELIMITER ;

关于MySQL存储过程的相关资料:

http://www.cnblogs.com/xnxylf/archive/2009/09/21/1571195.html

http://www.cublog.cn/u/14321/showart_153404.html

http://www.cnblogs.com/hsqzzzl/archive/2008/02/21/1076646.html

http://www.ccvita.com/100.html

http://www.php100.com/html/webkaifa/database/Mysql/2009/0418/1185.html

MySQL存储过程是一些预定义的 SQL 语句集合,可以在需要时执行。以下是MySQL存储过程的基本语法: ```sql CREATE PROCEDURE procedure_name() BEGIN -- SQL statements END; ``` 其中 `procedure_name` 是你要创建的存储过程的名称。`BEGIN` 和 `END` 之间是存储过程的主体,其中包含一系列 SQL 语句。 下面是一个简单的 MySQL 存储过程示例,它接受一个输入参数并返回一个输出参数: ```sql CREATE PROCEDURE get_customer(IN customer_id INT, OUT customer_name VARCHAR(255)) BEGIN SELECT name INTO customer_name FROM customers WHERE id = customer_id; END; ``` 在上面的示例中,我们创建了一个名为 `get_customer` 的存储过程,它接受一个整数类型的输入参数 `customer_id`,并声明一个变量 `customer_name` 作为输出参数。在存储过程的主体中,我们使用 `SELECT INTO` 语句从 `customers` 表中获取客户名,并将其赋值给 `customer_name` 变量。 要执行存储过程,你可以使用 `CALL` 语句: ```sql CALL get_customer(1, @name); SELECT @name; ``` 在上面的示例中,我们使用 `CALL` 语句调用 `get_customer` 存储过程,并将 `1` 作为输入参数传递。我们使用 `@name` 变量来存储存储过程返回的客户名,并在后续的 `SELECT` 语句中使用该变量。 这只是一个简单的示例,MySQL 存储过程可以执行更复杂的任务,包括控制流语句(例如 `IF` 和 `WHILE`)、游标和异常处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值