我有两个表数量(用户,年份,数量)和MonthlyQuantity(用户,年,月,数量) - 每月一个表是空的。 我需要做的是根据年度表填写每月表,将年度数量除以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;
答案 0 :(得分:1)
使用single statement,单集操作通常比许多小操作快得多:
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);