Массовая вставка вместо цикла в PLSQL? - PullRequest
1 голос
/ 17 января 2012

Я пытаюсь решить этот фрагмент кода с помощью массовой вставки или чего-то более эффективного, но у меня нет идей Как бы вы подошли к этой проблеме. Вместо того, чтобы делать так много раз, я бы хотел сделать это более эффективным за несколько звонков. Пожалуйста, дайте мне знать, как бы вы сделали? С кодом, если это возможно! Thanx

LOOP
-- Fetch a row
IF DBMS_SQL.FETCH_ROWS(cursor_handle) > 0 THEN
    DBMS_SQL.column_value(cursor_handle, 9, cont_id); 
    DBMS_SQL.COLUMN_VALUE(cursor_handle, 3, proj_nr);  
    HTP.BOLD('ContractID: ' || cont_id || ' ProjectNR: ' ||  proj_nr);
    HTP.BR;
ELSE
    EXIT;
END IF;

-- delete the old list before saving a new one
IF sek_nr = 1 THEN
  EXECUTE IMMEDIATE 'DELETE FROM W_Contracts WHERE user_id = :n' USING CURRENTUSER;
END IF;

EXECUTE IMMEDIATE 'Insert into W_Contracts values(''' || currentUser || ''', '
                   || sek_nr || ', sysdate, ' || cont_id || ', '''
                   || proj_nr || ''')';

sek_nr := sek_nr + 1;
END LOOP;

1 Ответ

8 голосов
/ 17 января 2012

Прежде всего, мне не понятно, почему вы используете динамический SQL, а не статический SQL.

IF sek_nr = 1 
THEN
  DELETE FROM w_contracts
   WHERE user_id = currentUser;
END IF;

INSERT INTO w_contracts( <<list of columns>> )
  VALUES( currentUser, sek_nr, sysdate, cont_id, proj_nr );

Далее, для меня не очевидно, почему вы потенциально делаете DELETE, а затем INSERT, если SEK_NR равно 1. Вероятно, было бы более эффективным сделать UPDATE в этом случае. И как только вы делаете UPDATE и INSERT, вы можете упростить это в один оператор MERGE.

Далее, если вы используете DEFINE_ARRAY метод в DBMS_SQL, вы можете выполнять массовую выборку данных с вашего курсора. Конечно, не видя вашего определения курсора, я бы заподозрил, что он тоже использует динамический SQL без необходимости и что вы можете использовать гораздо более простой подход.

...