четверг, 21 января 2016 г.

Особенности сравнения таблиц из записей %ROWTYPE

Имеем таблицы в двух схемах
create table MESSAGE
(
  message_id        INTEGER not null,
  message_code   VARCHAR2(128) not null,
  message_name  NVARCHAR2(256) not null,
  message_type   VARCHAR2(128) not null,
  message_level   INTEGER not null,
);

И процедуру сравнения содержимого в двух схемах
DECLARE
  TYPE t_m_tbl    IS TABLE OF message%ROWTYPE INDEX BY BINARY_INTEGER;
  v_sql1         CLOB;
  v_sql2         CLOB;
  v_cur1         SYS_REFCURSOR;
  v_cur2         SYS_REFCURSOR;

  v_m_tbl1       t_m_tbl;
  v_m_tbl2       t_m_tbl;
BEGIN
  v_sql1  := 'SELECT t.*
                FROM schema1.message t
              ORDER BY t.message_code';
  v_sql2  := 'SELECT t.*
                FROM schema2.message t
              ORDER BY t.message_code';          
  OPEN v_cur1 FOR v_sql1;
  FETCH v_cur1 BULK COLLECT INTO v_m_tbl1;
 
  OPEN v_cur2 FOR v_sql2;
  FETCH v_cur2 BULK COLLECT INTO v_m_tbl2;

  IF v_m_tbl1.count >0 THEN
    FOR prc_m1 IN v_m_tbl1.first..v_m_tbl1.last LOOP
    .................
    END LOOP;
  END IF;
END;

Если таблицы в разных схемах будут иметь одинаковую структуру но разную последовательность полей то получим ошибку не совместимости типов в строке
  FETCH v_cur1 BULK COLLECT INTO v_m_tbl1;
или
  FETCH v_cur2 BULK COLLECT INTO v_m_tbl2;

проблема решается явным перечислением полей в запросе
вместо t.* указать
t.message_id,
t.message_code,
t.message_name,
t.message_type,
t.message_level