0

我有两个表 Quantity(user, year, quantity) 和 MonthlyQuantity(user, year, month, quantity) - 每月一个是空的。我需要做的是根据年度表填写月表,将年度数量分成 12 个相等的部分,然后将任何剩余部分添加到上个月。所以基本上,Quantity 中的每一行都应该在 QuantityMonthly 中创建 12 行。这就是我的做法 - 问题是循环非常慢。

我怎样才能做得更快?

    create ro replace 
procedure pr_test
AS
BEGIN
    FOR r IN (SELECT * FROM Quantity) LOOP

    DELETE FROM QuantityMonthly qm WHERE qm.company = r.company AND qm.year = r.year;

    INSERT ALL
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 1, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 2, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 3, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 4, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 5, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 6, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 7, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 8, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 9, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 10, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 11, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 12, trunc(r.quantity / 12) + mod(r.quantity , 12))
  SELECT * FROM dual;

END LOOP;

COMMIT;

END pr_test;
4

1 回答 1

1

使用单个语句,单个集合操作通常比许多小操作快得多:

MERGE INTO QuantityMonthly qm
 USING (SELECT *
          FROM Quantity q
         CROSS JOIN (SELECT rownum mon
                       FROM dual
                    CONNECT BY level <= 12)) q
    ON (qm.company = q.company
        AND qm.year = q.year
        AND qm.mon = q.mon)
WHEN MATCHED THEN
   UPDATE SET qm.quantity = q.quantity / 12 
                            + CASE WHEN q.mon = 12 THEN 
                                 mod(r.quantity, 12) 
                              ELSE 
                                 0 
                              END
WHEN NOT MATCHED THEN
   INSERT (company, year, mon, qty)
   VALUES (q.company, q.year, q.mon,
           q.quantity / 12 
           + CASE WHEN q.mon = 12 THEN mod(r.quantity, 12) ELSE 0 END);
于 2012-09-27T12:14:08.547 回答