PLS-00436: ограничение реализации: нельзя ссылаться на поля таблицы записей BULK In-BIND - PullRequest
1 голос
/ 15 февраля 2012

Я получаю эту ошибку, когда вызываю процедуру 'archive_things', которая, в свою очередь, выдает ошибку в INSERT INTO deleted_part_things<br> (id, part_id, file_name, file_type, thing, editable)

что это значит?

 PROCEDURE archive_things ( p_part_id IN NUMBER ) 
 IS    
  thing_list  bean_list;
 BEGIN

 thing_list := get_thingss_info(p_part_id);

 insert_deleted_things(thing_list);

 END archive_things;



 FUNCTION get_things_info ( p_part_id IN NUMBER)
  RETURN bean_list
 IS
  attachment_list  bean_list;
 BEGIN

  SELECT file_thing_bean (id, hot_part_id, file_name, file_type, thing, editable)
  BULK COLLECT INTO thing_list
  FROM part_things
  WHERE part_id =hot_part_id;

  RETURN thing_list;

END get_things_info;



PROCEDURE insert_deleted_things(  p_bean_list IN bean_list ) 

IS BEGIN    

FORALL x IN INDICES OF p_bean_list       
    INSERT INTO deleted_part_things
        (id, part_id, file_name, file_type, thing, auditable)  <<<<<  ERROR HERE!!!!!     
         VALUES 
         (   p_bean_list(x).id, p_bean_list(x).parent_id,  p_bean_list(x).file_name,  p_bean_list(x).file_type,
              p_bean_list(x).thing,   p_bean_list(x).editable
        );             

     END insert_deleted_things;  

Ответы [ 2 ]

3 голосов
/ 16 февраля 2012

Два очка:

  1. В своем последнем вопросе вы упомянули, что используете Oracle 10g.Как Олли указал в своем ответе, вы не можете использовать метод, который используете до 11 г.
  2. Почему вы создаете две процедуры и функцию?Это легко может быть одна процедура.Поскольку первоначальная процедура, которую вы вызываете, вызывает две другие, вы ничего не получаете, разбивая ее и делая ее намного более сложной.ссылочные столбцы в rowtype в forall.Есть несколько способов обойти это:

    Во-первых, как предположил Олли, в вашей таблице должно быть столько же столбцов, сколько в bulk collect.Это не всегда возможно.

    Том Кайт предлагает операции над множествами.Ограничением является размер bulk collect, который вы делаете.Если оно больше, чем количество отмен, у вас будут проблемы.Кроме того, если вы хотите сделать что-то еще с данными, то вы должны сделать это отдельно.

    Последний вариант (я знаю, что я уверен, что их больше) состоит в том, чтобы собрать ваши записи в отдельные types вместо rowtype согласно следующему.Недостатком этого является то, что он может быть не таким быстрым, как метод Тома, и он ни в коем случае не так ясен, как метод Олли.

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

    PROCEDURE archive_things ( p_part_id IN NUMBER ) IS
    
       CURSOR c_get_all ( Cpart_id char) is
          SELECT file_attachment_bean (id, hot_part_id, file_name
                             , file_type, attachment, auditable)
            FROM hot_part_attachments
           WHERE hot_part_id = Cpart_id;
    
       t_id bean_list.id%type;
       t_hot_part_id bean_list.hot_part_id%type;
       t_file_name bean_list.file_name%type;
       t_file_type bean_list.file_type%type;
       t_attachment bean_list.attachment%type;
       t_auditable bean_list.auditable%type;
    
    BEGIN
    
       OPEN c_get_all(p_part_id);
       FETCH c_get_all bulk collect into
         t_id, t_hot_part_id, t_file_name, t_file_type, t_attachment, t_auditable;
    
       LOOP
    
          EXIT WHEN t_id.count = 0;
    
          FORALL x IN t_id.first .. t_id.last       
             INSERT INTO deleted_hot_part_attachments (id, hot_part_id, file_name, file_type
                                                       , attachment, auditable)     
             VALUES ( t_id(x), t_hot_part_id(x), t_file_name(x), t_file_type(x)
                    , t_attachment(x), t_auditable(x) );
    
          COMMIT; -- You may want to do this outside the procedure.
    
       END LOOP;
    
       CLOSE c_get_all;
    
    END;
    
0 голосов
/ 20 августа 2017
SET SERVEROUTPUT ON;

declare

    cursor c1 IS select 

c_code,c_name,c_language
from t_country;

TYPE c1_tab is table of t_country%rowtype; 

c1_insert c1_tab;
l_count number:=0;

begin

open c1;
    loop    
    fetch c1 
    bulk collect into c1_insert
    limit 10000;    

         forall i in 1 .. c1_insert.count
        insert into t_country values (c1_insert(i).cCode,c1_insert(i).cName,c1_insert(i).cLanguage);

        commit;
     exit when c1%notfounD;
     end loop;
 CLOSE C1;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...