Повысить производительность при вставке курсора? - PullRequest
0 голосов
/ 22 января 2012

Я хотел бы спросить вас, как бы вы увеличили производительность вставки курсора в этом коде? Мне нужно использовать динамический plsql для извлечения данных, но я не знаю, как улучшить INSERT наилучшим образом. как Bulk Insert возможно? Пожалуйста, дайте мне знать с примером кода, если это возможно.

// Вот как я использую cur_handle:

    cur_HANDLE integer;
cur_HANDLE := dbms_sql.open_cursor;
DBMS_SQL.PARSE(cur_HANDLE, W_STMT, DBMS_SQL.NATIVE);
DBMS_SQL.DESCRIBE_COLUMNS2(cur_HANDLE, W_NO_OF_COLS, W_DESC_TAB);

LOOP
-- Fetch a row   
IF DBMS_SQL.FETCH_ROWS(cur_HANDLE) > 0 THEN
    DBMS_SQL.column_value(cur_HANDLE, 9, cont_ID); 
    DBMS_SQL.COLUMN_VALUE(cur_HANDLE, 3, proj_NR);    
ELSE
    EXIT;
END IF;

  Insert into w_Contracts values(counter, cont_ID, proj_NR);
counter := counter + 1;
END LOOP;

Ответы [ 3 ]

1 голос
/ 23 января 2012

Решение 1) Вы можете заполнить внутри цикла массив PL / SQL, а затем сразу после цикла вставить весь массив за один шаг, используя:

FORALL i in contracts_tab.first .. contracts_tab.last
  INSERT INTO w_contracts VALUES contracts_tab(i);

Решение 2) если v_stmt содержит допустимый оператор SQL, вы можете напрямую вставить данные в таблицу, используя

EXECUTE IMMEDIATE 'INSERT INTO w_contracts (counter, cont_id, proj_nr) 
    SELECT rownum, 9, 3 FROM ('||v_stmt||')';
1 голос
/ 22 января 2012

Вы должны выполнять действия с базой данных в наборах, когда это возможно, а не построчно.Вы не говорите нам, что такое CUR_HANDLE, поэтому я не могу переписать это, но вы, вероятно, должны сделать что-то вроде:

INSERT INTO w_contracts
SELECT ROWNUM, cont_id, proj_nr
  FROM ( ... some table or joined tables or whatever... )

Хотя, если ваше первое значение - первичный ключ, оновероятно, было бы лучше назначить его из последовательности.

0 голосов
/ 24 января 2012

"оператор выбора выбирается с веб-сайта, например, если пользователь выбирает включить более подробный поиск, тогда оператор выбора изменяется и результат выглядит иначе в конце. Все приложение представляет собой веб Сайт построен на динамическом коде plsql. "

Это опасное предложение, поскольку оно открывает вашу базу данных для внедрения SQL. Это сценарий, в котором Плохие Люди подрывают ваши параметры, чтобы расширить данные, которые они могут получить, или повысить привилегии. По крайней мере, вам нужно использовать DBMS_ASSERT для проверки ввода пользователя. Узнать больше .

Конечно, если вы разрешаете пользователям передавать целые строки SQL (вы не предоставили никакой информации относительно конструкции W_STMT), тогда все ставки отменены. DBMS_ASSERT вам там не поможет.

В любом случае, поскольку вы не смогли предоставить дополнительную информацию, которая нам действительно необходима, пожалуйста, позвольте мне изложить ее для вас:

  • будет ли инструкция SELECT всегда иметь одинаковые имена столбцов из одного и того же имени таблицы, или пользователь может изменить эти два?
  • Вас всегда будут интересовать третий и девятый столбцы?
  • как собирается строка W_STMT? Насколько вы контролируете его проекцию?
...