我是高级JEE开发人员,但我是PL / SQL开发的新手,我需要老年Oracle开发人员的帮助。
我的问题是:
我需要在数据库中更新300万行。
我制作了一个在实验室数据库中运作良好的程序。
但是在生产数据库中,这真的很慢,我真的不想锁定数据库。
第一次尝试是创建此过程:
CREATE OR REPLACE
PROCEDURE "PR_UPDATE_R" AS
BEGIN
DBMS_OUTPUT.PUT_LINE ('1.Find measures...') ;
FOR obj IN (
SELECT SC.ID ID
FROM SIMET.TB_SC SC
JOIN SIMET.TB_D D ON D.HASH = SC.HASH
JOIN (
SELECT
T1.ID_D_FK,
MIN (T1.UPDATE_DATE) LIMIT_DATE
FROM
TB_SBVH T1
WHERE
T1. VERSION > 10000
GROUP BY
T1.ID_D_FK
) SBVH ON SBVH.ID_D_FK = D .ID_D_PK
WHERE
(
SBVH.LIMIT_DATE IS NULL OR SC.TIMESTAMP_CREATION < SBVH.LIMIT_DATE
)
AND
sc.TIMESTAMP_CREATION >= TO_TIMESTAMP ('2012-08-27 00:00:00.000000','yyyy-mm-dd hh24:mi:ss.ff')
AND
sc.MEASURE_TIMESTAMP_CREATION <= TO_TIMESTAMP ('2015-07-06 00:00:00.00000','yyyy-mm-dd hh24:mi:ss.ff')
)LOOP
UPDATE TB_R SET total = total + other_field WHERE id_m_fk = obj.ID ;
UPDATE tb_sc
SET TOTAL_PCT = (
SELECT
CASE WHEN SUM (r.total_sent) > 0 THEN (
100 * SUM (r.total_lost) / SUM (r.total_sent)
)
ELSE
0
END
FROM
tb_r r
WHERE
ID = obj.ID
)
WHERE
ID = obj.ID;
END LOOP;
DBMS_OUTPUT.PUT_LINE ('2.Finished!!!') ;
END ;
但是不是一个好主意,因为这个程序的主要查询(进入FOR循环),单独花了29分钟!!锁定数据库。
然后,
我的第二个想法是分享小的主要查询,bach,并用小循环运行它。
每次每天运行的新查询花费3秒钟。
而且,我的想法是:我将这个快速的日记查询放入一个循环中,每次运行30天30天:
SELECT
*
FROM
(
SELECT
SC.ID_M_FK,
SC.TIMESTAMP_CREATION,
D.ID_D_PK
FROM
TB_SC SC
JOIN TB_D D ON D.HASH = SC.HASH
WHERE
SC.TIMESTAMP_CREATION >= TIMESTAMP '2013-02-06 00:00:00.000'
AND SC.TIMESTAMP_CREATION < TIMESTAMP '2013-02-07 00:00:00.000'
AND SC.IS_ACTIVE = 1
) CD -- CACHE_DATA
JOIN (
SELECT
T1.ID_D_FK,
MIN (T1.UPDATE_DATE) LIMIT_DATE
FROM
TB_SBVH T1
WHERE
T1. VERSION > 10000
GROUP BY
T1.ID_D_FK
) SBVH ON SBVH.ID_D_FK = CD.ID_D_PK
WHERE
(
SBVH.LIMIT_DATE IS NULL
OR
CD.TIMESTAMP_CREATION < SBVH.LIMIT_DATE
)
;
但在这个问题中I can use a timestamp variable on query of cursor in a store procedure? 很多人告诉我这不是一个好的解决方案。
有人可以帮我吗?