2016-01-07 6 views
0

Почему я не могу выполнить запрос stmt?plsql: выполнить запрос: неверный идентификатор

Показаны tabb Недействительный идентификатор.

TYPE tab_row IS TABLE OF tab_name%ROWTYPE; 
    tabb tab_row; 
    TYPE cur_ref Is Ref Cursor; 
    c   cur_ref; 
    stmt_string Varchar2(1000); 
    stmt Varchar2(1000); 
Begin 
    stmt_string := 'Select * from ' || tab1 || ' mft 
      Where mft.mfmt_id IS NOT NULL 
      and mft.MFMT_FLAG IS NULL'; 
    Open c For stmt_string; 
    Fetch c bulk collect into tabb; 
    Close c; 
stmt:= 'Update '|| tab || ' m 
    Set m.mfmt_mat_bnr = tabb(i).mfmt_mat_bnr, 
    m.mfmt_mat_type = tabb(i).mfmt_mat_type, 
    m.mfmt_be_seg = tabb(i).mfmt_be_seg 
    Where m.mfmt_id = tabb(i).mfmt_id'; 

    For i in 1..tabb.count loop  
    Execute Immediate stmt; 
    End loop; 
End; 
+0

Что это Tabb? Где это объявляется? – Hawk

+0

tabb - таблица сбора – kmy

ответ

0

Я не видел, где находится tabb. Как вы упомянули в своем комментарии, это коллекция.

Из вашего кода я могу понять, что вы перебираете значения этой коллекции. Это означает, что эти значения: переменные т. Е. Изменение значений на каждой итерации. Поэтому вам необходимо использовать их как таковые.

Текущий динамический оператор, это значения статической строки. Это Set m.mfmt_mat_bnr = tabb(i).mfmt_mat_bnr, приведет к тому, что одна и та же строка будет продолжена. Следовательно, вам нужно изменить, что Set m.mfmt_mat_bnr = '|| tabb(i).mfmt_mat_bnr||', ...etc

Я могу переписать код следующим образом:

TYPE tab_row IS TABLE OF tab_name%ROWTYPE; 
tabb tab_row; 
TYPE cur_ref Is Ref Cursor; 
c   cur_ref; 
stmt_string Varchar2(1000); 
stmt Varchar2(1000); 
Begin 
stmt_string := 'Select * from ' || tab1 || ' mft 
      Where mft.mfmt_id IS NOT NULL 
      and mft.MFMT_FLAG IS NULL'; 
Open c For stmt_string; 
Fetch c bulk collect into tabb; 
Close c; 
stmt:= 'Update '|| tab || ' m 
Set m.mfmt_mat_bnr = '||tabb(i).mfmt_mat_bnr||', 
m.mfmt_mat_type = '||tabb(i).mfmt_mat_type||', 
m.mfmt_be_seg = '||tabb(i).mfmt_be_seg||' 
Where m.mfmt_id = '||tabb(i).mfmt_id; 

For i in 1..tabb.count loop  
    Execute Immediate stmt; 
    End loop; 
End; 

Поскольку этот код не проверял, одна вещь, которую я настоятельно рекомендую, чтобы подтвердить первым. Это то, что tabb правильно объявлено в пределах области действия.

0

Если проблема в вашей петле, где вы выполняете свое утверждение, возможно, попробуйте использовать оператор EXECUTE IMMEDIATE .. USING?

синтаксис:

EXECUTE IMMEDIATE <SQL Command> 
     [INTO <variable list>] 
     [USING <bind variable list>]; 

Вы можете попробовать этот код, а затем:

DECLARE 
     -- your tab1 may contain some insignificant columns with values (especially huge ones e.g. CLOB/BLOB) 
     -- which will extremely affect procedure's efficiency, so it's a better practice to select only those values that we need 
     TYPE t_tab_rec IS RECORD (
      mfmt_mat_bnr    tab_name.mfmt_mat_bnr%TYPE 
      ,mfmt_mat_type    tab_name.mfmt_mat_type%TYPE 
      ,mfmt_be_seg    tab_name.mfmt_be_seg%TYPE 
      ,mfmt_id     tab_name.mfmt_id%TYPE 
     ); 

     TYPE t_tab_arr IS TABLE OF t_tab_rec; 
     tabb   t_tab_arr := NEW t_tab_arr(); 
     TYPE ref_cur IS REF CURSOR RETURN t_tab_rec; -- to assure cursor is returning t_tab_rec type records 
     c    cur_ref; 
     stmt_select  VARCHAR2(1000); 
     stmt_upadte  VARCHAR2(1000); 
    BEGIN 

     stmt_select := 
      'SELECT 
       mft.mfmt_mat_bnr 
       ,mft.mfmt_mat_type 
       ,mft.mfmt_be_seg 
       ,mft.mfmt_id 
      FROM 
       '||tab1||' mft 
      WHERE 
       mft.mfmt_id IS NOT NULL 
       AND mft.mfmt_flag IS NOT NULL'; 

     OPEN c FOR stmt_select; 
     FETCH c BULK COLLECT INTO tabb; 
     CLOSE c; 

     stmt_upadte := 
      'UPDATE '||tab||' 
      SET mfmt_mat_bnr = :p_mfmt_mat_bnr 
       ,mfmt_mat_type = :p_mfmt_mat_type 
       ,mfmt_be_seg = :p_mfmt_be_seg 
      WHERE 
       mfmt_id = :p_mfmt_id'; 

     FOR idx IN tabb.FIRST .. tabb.LAST 
     LOOP 
      EXECUTE IMMEDIATE stmt_update USING tabb(idx).mfmt_mat_bnr, tabb(idx).mfmt_mat_type, tabb(idx).mfmt_be_seg, tabb(idx).mfmt_id; 
     END LOOP; 

    END; 
    /
Смежные вопросы