我想在id列的基础上添加存储过程中两个表的工资:
器DD1:
create table salary1 (id varchar(20), salary varchar(20));
create table salary2 (id varchar(20), salary varchar(20));
DML:
insert into salary1 values('1', '100');
insert into salary1 values('2', '200');
insert into salary2 values('1', '10');
insert into salary2 values('2', '10');
数据库: mysql
输出应该是:
id total_sal
1 110
2 210
我的存储过程如下:
CREATE PROCEDURE totalSal()
BEGIN
DECLARE tbl1_id varchar(30);
DECLARE tbl1_sal varchar(30);
DECLARE tbl2_id varchar(30);
DECLARE tbl2_sal varchar(30);
DECLARE total_sal varchar(30);
DECLARE c1 CURSOR FOR SELECT * FROM salary1;
DECLARE c2 CURSOR FOR SELECT * FROM salary2;
-- Open first cursor
OPEN c1;
LOOP
FETCH c1 INTO tbl1_id, tbl1_sal;
-- Open second cursor
OPEN c2;
LOOP
FETCH c2 INTO tbl2_id, tbl2_sal;
IF tbl1_id = tbl2_id THEN
set total_sal := tbl1_sal + tbl2_sal;
ELSE
set total_sal := tbl_sal;
END IF;
END LOOP;
CLOSE c2;
END LOOP;
CLOSE c1;
end $$
它已成功编译,但是当我运行该程序时,我收到以下错误:
错误1329(02000):无数据 - 提取,选择或处理零行
我在我的程序中也使用了DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
。但我的问题仍未得到解决。
如果有人能在oracle中解决这个问题,那对我也有帮助。
注意:我无法对这些表执行join
操作。由于一些性能问题。
在此先感谢!!!
答案 0 :(得分:1)
解决方案1:
Using collection and only one iteration of 2 loop
您应该考虑在join
上解决性能问题。在大多数情况下,执行循环比设定的基本方法慢。
如果我按照你的逻辑,你真正想要的是循环通过每个salary1行的所有salary2表,以便找到正确的ID =>数以百万计的循环。
您可以考虑在内部和索引数组中进行2个独立的循环和存储数据。 (键将是tlb1_id)。 如果密钥存在:将工资值相加,如果不存在,则将其插入数组中。
在程序结束时,只需选择数组作为表格。
解决方案2:
Using a join on integer indexed columns
看看这个小提琴http://sqlfiddle.com/#!9/c445de/1,执行这些步骤和耗尽磁盘空间以便添加新的列和索引可能会非常耗时,但是连接操作可能比以前更快。
答案 1 :(得分:0)
你可以做这样的事情......我已经将第二个光标移动到循环内部,以便它只能覆盖表1中的id。这应该有助于程序的逻辑,但我还是会建议试图找出如何修复连接以获得结果,因为这似乎是一种更简单的方法,如果正确完成应该更快。
CREATE PROCEDURE totalSal()
BEGIN
DECLARE tbl1_id varchar(30);
DECLARE tbl1_sal varchar(30);
DECLARE tbl2_id varchar(30);
DECLARE tbl2_sal varchar(30);
DECLARE total_sal varchar(30);
DECLARE c1 CURSOR FOR SELECT * FROM salary1;
-- Open first cursor
OPEN c1;
LOOP
FETCH c1 INTO tbl1_id, tbl1_sal;
SELECT COUNT(*) INTO v_rowcount FROM salary2 WHERE id = tbl1_id;
IF v_rowcount > 0 THEN
Begin
DECLARE c2 CURSOR FOR SELECT * FROM salary2 WHERE id = tbl1_id;
-- Open second cursor
OPEN c2;
LOOP
FETCH c2 INTO tbl2_id, tbl2_sal;
IF tbl1_id = tbl2_id THEN
set total_sal := tbl1_sal + tbl2_sal;
ELSE
set total_sal := tbl_sal;
END IF;
END LOOP;
CLOSE c2;
END IF;
END
END LOOP;
CLOSE c1;
end $$
答案 2 :(得分:0)
嗯,你问了没有JOIN
的答案,但这似乎是随意的,所以这是JOIN
的答案。
SELECT
sums1.id
, S1Sum + S2Sum AS SalarySum
FROM (SELECT id, SUM(CAST(salary AS int)) AS S1Sum
FROM salary1
GROUP BY id) sums1
JOIN (SELECT id, SUM(CAST(salary AS int)) AS S2Sum
FROM salary2
GROUP BY id) sums2
ON sums1.id = sums2.id
我猜您的效果不好,因为您的所有列都应为varchar
int
或numeric
。但是我们没有太多可以继续下去,所以希望这有助于你找到一个可靠的解决方案。
此帖也被编辑以添加MySQL和Oracle标签,因此很难确定语法应该是什么......