需要验证我的 pl/sql 代码并且需要我的所有版本

问题描述 投票:0回答:1

我的团队有一张桌子ace_1

STATUS CHARGE_1 CHARGE_2
N   5   20
Y   7   25
N   9   30
N   11  35
Y   13  40

当每个 CHARGE_1/ACTION=CREATE 和 CHARGE_2/ACTION=UPDATE 的 STATUS=N 时,需要 INSERT INTO table ace_2 两行 当 STATUS=N 且 ACTION=CREATE 且 CHARGES=CHARGE_1 时仅插入一行,如下

ace_2

STATUS ACTION CHARGES
N   CREATE  5
N   UPDATE  20
Y   CREATE  7
N   CREATE  9
N   UPDATE  30
N   CREATE  11
N   UPDATE  35
Y   CREATE  13

我的以下程序运行良好。 但是还有其他选项可以使用 FORALL LOOP 来微调代码吗? 实时数据在0.1到100万之间。需要解决性能问题。

PROCEDURE test1 (
        x_status_code   OUT VARCHAR2,
        x_error_message OUT VARCHAR2
    ) IS

        CURSOR cur_a IS
        SELECT
            *
        FROM
            ace_1
        WHERE
            1 = 1;

        TYPE ace_1_tbl_type IS
            TABLE OF cur_a%rowtype INDEX BY PLS_INTEGER;
        lvar_1 ace_1_tbl_type;
    BEGIN
        OPEN cur_a;
        LOOP
            FETCH cur_a
            BULK COLLECT INTO lvar_1 LIMIT 100;
            EXIT WHEN lvar_1.count = 0;
            FOR idx IN 1..lvar_1.count LOOP
                IF lvar_1(idx).status = 'Y' THEN
                    INSERT INTO ace_2 VALUES (
                        lvar_1(idx).status,
                        'CREATE',
                        lvar_1(idx).charge_1
                    );

                ELSIF lvar_1(idx).status = 'N' THEN
                    INSERT INTO ace_2 VALUES (
                        lvar_1(idx).status,
                        'CREATE',
                        lvar_1(idx).charge_1
                    );

                    INSERT INTO ace_2 VALUES (
                        lvar_1(idx).status,
                        'UPDATE',
                        lvar_1(idx).charge_2
                    );

                END IF;

                END IF;

            END LOOP;

        END LOOP;

        CLOSE cur_a;
         dbms_output.put_line('END WELL');
    EXCEPTION
        WHEN OTHERS THEN
            dbms_output.put_line('INTO EXCEPTION' || x_error_message);
            x_status_code := sqlcode;
            x_error_message := sqlerrm;
            dbms_output.put_line('fine 123');
    END test1;
validation plsql bulk collect forall
1个回答
0
投票

您可以使用单个插入语句来完成此操作,例如:

insert into ace_2 (status, action, charges)
with dummy as (select level id
               from   dual
               connect by level <= 2)
select a1.status,
       case when d.id = 1 then 'CREATE' else 'UPDATE' end action,
       case when d.id = 1 then a1.charge_1 else a1.charge_2 end charges
from   ace_1 a1
       inner join dummy d on a1.status = 'N' or (a1.status = 'Y' and d.id = 1);

这是通过将

ace_1
表中的行连接到包含 2 行的一组数据(在
dummy
子查询中使用
connect by
技巧生成指定级别数的行)来实现的,这样状态为 Y 的行仅与第一个虚拟行匹配,而状态 N 行与两个虚拟行匹配。

获得该数据后,只需将其插入到 ace_2 表中即可。

但是,您提供的数据没有任何暗示排序的列或链接行集的键,因此您获得的结果不一定看起来像您的预期输出,正如您从 this db<> 中看到的那样小提琴.

假设您的实际数据具有这些列,那么您应该很容易应用上述技术,然后相应地对输出进行排序。

© www.soinside.com 2019 - 2024. All rights reserved.