ora-02393超出呼叫CPU使用限制(Oracle) - 如何解决方法

时间:2016-02-03 05:19:38

标签: oracle

我有函数来计算特定合约的IRR(内部收益率)。

此函数在简单过程中调用,并应用于已定义表中的所有合同。

问题是,有大约200k行需要更新..并且函数calc_IRR()不是那么有效(循环和子循环),这是计算正确值所必需的。

运行一小时后,查询将超过CALL CPU USAGE限制(ora-02393)并且查询结束..但我需要再次重新运行查询...

程序来了:

java.lang.RuntimeException: Unable to start activity ComponentInfo{myapps.com.workhours/myapps.com.workhours.ViewDateResult}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2316)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2376)
        at android.app.ActivityThread.access$800(ActivityThread.java:147)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1281)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5253)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

如果没有手动输入用户怎么办?我把它放在PACKAGE中,所以每个月都会自动调用一次......

1 个答案:

答案 0 :(得分:0)

将过程从逐行转换为单个SQL语句。这种类型的转换通常可以显着提高性能,因为它减少了SQL和PL / SQL之间的上下文切换次数。

CREATE OR REPLACE PROCEDURE proc_set_irr (
    p_table_name IN VARCHAR2,
    p_cashflow_column IN VARCHAR2,
    p_dimension IN VARCHAR2,
    p_irr_column IN VARCHAR2
) is
begin
    execute immediate replace(replace(replace(replace(
        q'[
            merge into #P_TABLE_NAME
            using
            (
                select distinct #P_DIMENSION
                from #P_TABLE_NAME
                where #P_IRR_COLUMN is null
            ) null_irr
                on (null_irr.#P_DIMENSION = #P_TABLE_NAME.#P_DIMENSION)
            when matched then update set 
                #P_IRR_COLUMN = f_calc_irr(
                    '#P_TABLE_NAME',
                    '#P_CASHFLOW_COLUMN',
                    '#P_DIMENSION = '||null_irr.#P_DIMENSION)*100
        ]'
        , '#P_TABLE_NAME', p_table_name)
        , '#P_DIMENSION', p_dimension)
        , '#P_IRR_COLUMN', p_irr_column)
        , '#P_CASHFLOW_COLUMN', p_cashflow_column
    );

    commit;
end proc_set_irr;
/

还有一些其他的小改动:

  1. 将UPDATE更改为MERGE以避免连接两次(一次用于条件,一次用于值)。
  2. 使用备用引用机制和REPLACE将字符串连接更改为模板。这有助于减少引号的数量,但它仍然有点凌乱。
  3. 删除了异常处理程序。除非代码以某种方式处理错误或添加调试信息,否则捕获和提升是没有意义的。默认错误消息包含的信息多于自定义RAISE_APPLICATION
  4. 中的信息