2015-01-27 7 views
0

Я застрял внизу и получил синтаксическую ошибку. Пожалуйста, помогите. В основном я использую коллекцию для хранения нескольких идентификаторов отдела, а затем хотел бы использовать эти идентификаторы отдела в качестве условия фильтра при вставке данных в таблицу emp в инструкции FORALL.FORALL + EXECUTE IMMEDIATE + INSERT Into tbl SELECT

Ниже приведен пример кода: при компиляции этого кода. Я получаю сообщение об ошибке. Мое требование - использовать таблицу INSERT INTO, выбрать * из таблицы и не избежать этого, пожалуйста, предложите.

create or replace Procedure abc(dblink VARCHAR2) 
CURSOR dept_id is select dept_ids from dept; 
TYPE nt_dept_detail IS TABLE OF VARCHAR2(25); 
l_dept_array nt_dept_detail; 
Begin 
OPEN dept_id; 
FETCH dept_id BULK COLLECT INTO l_dept_array; 
IF l_dept_array.COUNT() > 0 THEN 

    FORALL i IN 1..l_dept_array.COUNT SAVE EXCEPTIONS 
     EXECUTE IMMEDIATE 'INSERT INTO stg_emp SELECT 
     Dept,''DEPT_10'' FROM dept_emp'||dblink||' WHERE 
     dept_id = '||l_dept_array(i)||'';  
     COMMIT; 
END IF; 
CLOSE dept_id; 
end abc; 
+2

Вы собираетесь сказать нам, что ошибка, или мы должны угадать? – OldProgrammer

+1

Насколько сложно скопировать данные сессии, включая стек ошибок. Просто выполните его в SQL * Plus и скопируйте содержимое. –

+0

Если вы получаете сообщение типа «скомпилировано с предупреждениями» или «см. Журнал компилятора», в некоторых клиентах вы можете использовать «show errors» для просмотра актуальных проблем; и вы можете запросить представление 'user_errors' от любого клиента. –

ответ

5

Почему вы пытаетесь использовать курсоры, массивы и т. Д. В первую очередь? Почему вы не можете просто сделать простую вставку, как выбрать?

Проблемы с процедурой, как указано выше:

  1. Вы не объявляете процедуры, как Procedure abc() - для автономной процедуры, вы могли бы сделать create or replace procedure abc as, или в пакете: procedure abc is

  2. You ссылку на переменную, называемую «dblink», которая нигде не объявлена.

  3. Вы не поставили end abc; в конце вашей процедуры (я надеюсь, что это просто неправильно с & р?)

  4. Вы эффективно делать простую вставку, как выбрать, но вы переутомляя его, плюс вы делаете свой код менее эффективным.

  5. Вы не указали имена столбцов, которые вы пытаетесь вставить; если stg_emp имеет более двух столбцов или заканчивается добавлением столбцов, ваш код будет терпеть неудачу.


Если предположить, что имя DBLink не известно до времени выполнения, то здесь что-то, что будет делать то, что вы после:

create Procedure abc (dblink in varchar2) 
is 
begin 
    execute immediate 'insert into stg_emp select dept, ''DEPT_10'' from [email protected]'||dblink|| 
        ' where dept_id in (select dept_ids from dept)'; 
    commit; 
end abc; 
/

Если, однако, вы знаете DBLink имя , то вы просто избавитесь от немедленного выполнения и выполните:

create Procedure abc (dblink in varchar2) 
is 
begin 
    insert into stg_emp -- best to list the column names you're inserting into here 
    select dept, 'DEPT_10' 
    from [email protected] 
    where dept_id in (select dept_ids from dept); 
    commit; 
end abc; 
/
+2

Также ссылается на 'l_l_dept_array' в' FORALL', а не 'l_dept_array'. –

+0

хорошее место; Я не слишком внимательно смотрел на вызовы массивов – Boneist

+0

Спасибо ... я только что вставил образец кода ... все в порядке, за исключением того, что выполняйте немедленное и вставьте туда, где я получаю ошибку компиляции. – user1717270

1

Похоже, что с этим кодом будет много ошибок. 1) почему немедленное исполнение? Есть ли явное требование для этого? Нет, чем не использовать его 2) где объявлена ​​переменная dblink? 3) как уже писал Бонист, почему не простой подзаголовок в инструкции insert? INSERT INTO stg_emp SELECT Dept, 'DEPT_10' FROM dept_emp @ dblink WHERE dept_id in (выберите dept_ids из отдела);

С одной стороны, это сделало бы код на самом деле читаемый;)

+1

Если (большая, если!) переменная dblink на самом деле является переменной и не известна во время выполнения, тогда динамический sql является единственным путь. Если это известно, то я согласен, совершенно не нужно динамическое sql! – Boneist

+0

Ссылка db будет известна во время выполнения, поэтому я должен использовать динамический SQL – user1717270

+0

. Это хорошая причина. Но все же вы можете использовать запрос, который я записал, и получить те же результаты. В использовании динамического SQL-файла вряд ли стоит штрафов за производительность, но вы должны избегать его для очевидных условий чтения и кода.

 Смежные вопросы

  • Нет связанных вопросов^_^