我应该使用什么:动态SQL,静态SQL或Oracle数据库中的其他解决方案

时间:2016-02-19 13:19:43

标签: sql oracle plsql

我是高级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? 很多人告诉我这不是一个好的解决方案。

有人可以帮我吗?

0 个答案:

没有答案