如何在存储过程中添加两个表的工资

时间:2018-02-15 17:14:13

标签: mysql sql

我想在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操作。由于一些性能问题。 在此先感谢!!!

3 个答案:

答案 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
  1. 您可以在每个表上添加新的整数列
  2. 使用ID列的转换值
  3. 填充此列
  4. 在每张表的这些列上添加索引
  5. 之后您将能够执行加入
  6. 看看这个小提琴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 intnumeric。但是我们没有太多可以继续下去,所以希望这有助于你找到一个可靠的解决方案。

此帖也被编辑以添加MySQL和Oracle标签,因此很难确定语法应该是什么......