Использование BULK COLLECT с rownum - PullRequest
0 голосов
/ 26 июня 2018

Ниже запроса Bulk выбирает, а затем обновляет записи в цикле. Я хочу использовать конструкции BULK COLLECT INTO и FORALL для повышения производительности. Но запрос использует rownum для обновления столбца в цикле. Можно ли в любом случае использовать BULK COLLECT INTO при получении rownum?

     FOR rec IN
        (SELECT rownum rn,
            b.*
        FROM
            (SELECT *
            FROM temp_final a
           WHERE reid  = 1
            AND retype  = 9
            AND sid         = 'r123'
            AND pid = 2191
            ORDER BY a.horder DESC nulls last,
                sname                         ,
                rowgroup                           ,
                dpct DESC nulls last       ,
                name
            ) b
        )
        LOOP
            UPDATE temp_final
            SET horder=rec.rn
             WHERE reid  = 1
            AND retype  = 9
            AND sid         = 'r123'
            AND pid = 2191
            AND mid   =rec.mid;
        END LOOP;

Спасибо

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Вам не нужен массовый сбор, то, что пытается сделать ваше обновление pl / sql, можно переписать в виде одного оператора MERGE INTO, что будет намного эффективнее, чем использование FORALL. Если вы все еще настаиваете на использовании forall, вы можете преобразовать этот MERGE в блок forall.

MERGE INTO temp_final tgt USING (
    SELECT rowid,
        ROW_NUMBER() OVER(
            ORDER BY
                horder DESC NULLS LAST,sname,rowgroup,dpct DESC NULLS LAST,name
        ) rn
    FROM
        temp_final
    WHERE
        reid = 1
        AND retype = 9
        AND sid = 'r123'
        AND pid = 2191
)
src ON ( tgt.rowid = src.rowid )
WHEN MATCHED THEN UPDATE SET tgt.horder = src.rn;
0 голосов
/ 26 июня 2018

Вы можете захватить rowid вместе с начальным выбором, сбросить лот в массивы и затем использовать его в своем FORALL, например,

declare
  l_num_list sys.odcinumberlist := sys.odcinumberlist();
  l_char_list sys.odcivarchar2list := sys.odcivarchar2list();
begin  
SELECT rownum rn,rowidtochar(rid)
bulk collect into l_num_list, l_char_list
FROM
            (SELECT a.*, rowid rid
            FROM temp_final a
           WHERE reid  = 1
            AND retype  = 9
            AND sid         = 'r123'
            AND pid = 2191
            ORDER BY a.horder DESC nulls last,
                sname                         ,
                rowgroup                           ,
                dpct DESC nulls last       ,
                name
            ) b;

forall i in 1 .. l_num_list.count
            UPDATE temp_final
            SET horder=l_num_list(i)
            WHERE rowid = chartorowid(l_char_list(i));

end;
/
...