Oracle
 sql >> база данни >  >> RDS >> Oracle

Сравнете две схеми и актуализирайте старата схема с новите колони на новата схема

Инструмент за сравнение на схеми е добра идея. Схемата на базата данни е много по-сложна, отколкото повечето хора приписват, и всяка разлика между две схеми на база данни има потенциал да причини грешки.

Ако все още желаете да го направите сами, най-добрият подход, който открих, е да извлечете дефинициите на схемата в текст, след което да стартирате текстово сравнение. Докато всичко е подредено по азбучен ред, можете да използвате функцията за сравняване на документи в Microsoft Word (или FC.EXE, DIFF или еквивалент), за да подчертаете разликите.

Следният SQLPlus скрипт извежда дефиницията на схемата по азбучен ред, за да позволи сравнение. Има два раздела. Първият раздел изброява всяка колона във формат:

table_name.column_name: data_type = data_default <nullable>

Вторият раздел изброява индексите и ограниченията, както следва:

PK constraint_name on table_name (pk_column_list)
FK constraint_name on table_name (fk_column_list)
CHECK constraint_name on table_name (constraint_definition)

Скриптът служи като полезна справка за извличане на някои от подробностите на схемата на Oracle. Това може да е добра информация, която трябва да имате, когато сте навън в клиентски сайтове и не разполагате с обичайните си инструменти или когато политиките за сигурност ви пречат да получите достъп до база данни на клиентски сайт директно от собствения си компютър.

set serveroutput on;
set serveroutput on size 1000000;
declare
  rowcnt    pls_integer := 0;
  cursor c_column is
     select table_name, column_name, data_type, 
        data_precision, data_length, data_scale, 
        data_default, nullable,
        decode(data_scale, null, null, ',') scale_comma,
        decode(default_length, null, null, '= ') default_equals
      from all_tab_columns where owner = 'BCC'
      order by table_name, column_name;
  cursor c_constraint is
      select c.table_name, c.constraint_name,
         decode(c.constraint_type,
                'P','PK',
                'R','FK',
                'C','CHECK',
                 c.constraint_type) constraint_type,
         c.search_condition, 
         cc.column_1||cc.comma_2||cc.column_2||cc.comma_3||cc.column_3||cc.comma_4||cc.column_4||
         cc.comma_5||cc.column_5||cc.comma_6||cc.column_6||cc.comma_7||cc.column_7 r_columns   
       from all_constraints c,
          ( select owner, table_name, constraint_name, nvl(max(position),0) max_position,
             max( decode( position, 1, column_name, null ) ) column_1,
             max( decode( position, 2, decode(column_name, null, null, ',' ), null ) ) comma_2,
             max( decode( position, 2, column_name, null ) ) column_2,
             max( decode( position, 3, decode(column_name, null, null, ',' ), null ) ) comma_3,
             max( decode( position, 3, column_name, null ) ) column_3,
             max( decode( position, 4, decode(column_name, null, null, ',' ), null ) ) comma_4,
             max( decode( position, 4, column_name, null ) ) column_4,
             max( decode( position, 5, decode(column_name, null, null, ',' ), null ) ) comma_5,
             max( decode( position, 5, column_name, null ) ) column_5,
             max( decode( position, 6, decode(column_name, null, null, ',' ), null ) ) comma_6,
             max( decode( position, 6, column_name, null ) ) column_6,
             max( decode( position, 7, decode(column_name, null, null, ',' ), null ) ) comma_7,
             max( decode( position, 7, column_name, null ) ) column_7
           from all_cons_columns
           group by owner, table_name, constraint_name ) cc
       where c.owner = 'BCC'
       and c.generated != 'GENERATED NAME'
       and cc.owner = c.owner
       and cc.table_name = c.table_name
       and cc.constraint_name = c.constraint_name
       order by c.table_name, 
          decode(c.constraint_type,
                 'P','PK',
                 'R','FK',
                 'C','CHECK',
                 c.constraint_type) desc, 
          c.constraint_name;
begin
  for c_columnRow in c_column loop
    dbms_output.put_line(substr(c_columnRow.table_name||'.'||c_columnRow.column_name||': '||
                         c_columnRow.data_type||'('||
                         nvl(c_columnRow.data_precision, c_columnRow.data_length)||
                         c_columnRow.scale_comma||c_columnRow.data_scale||') '||
                         c_columnRow.default_equals||c_columnRow.data_default||
                         ' <'||c_columnRow.nullable||'>',1,255));
    rowcnt := rowcnt + 1;
  end loop;
  for c_constraintRow in c_constraint loop
    dbms_output.put_line(substr(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
                         c_constraintRow.table_name||' ('||
                         c_constraintRow.search_condition||
                         c_constraintRow.r_columns||') ',1,255));
    if length(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
                         c_constraintRow.table_name||' ('||
                         c_constraintRow.search_condition||
                         c_constraintRow.r_columns||') ') > 255 then
       dbms_output.put_line('... '||substr(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
                            c_constraintRow.table_name||' ('||
                            c_constraintRow.search_condition||
                            c_constraintRow.r_columns||') ',256,251));
    end if;
    rowcnt := rowcnt + 1;
  end loop;
end;
/

За съжаление има няколко ограничения:

  1. Вградените връщания на каретка и интервали в data_defaults и дефиниции на ограничения за проверка могат да бъдат осветени като разлики, въпреки че нямат ефект върху схемата.
  2. Не включва алтернативни ключове, уникални индекси или индекси за ефективност. Това ще изисква трета команда SELECT в скрипта, препращаща към каталожни изгледи all_ind_columns и all_indexes.
  3. Не включва подробности за сигурността, синоними, пакети, тригери и т.н. Пакетите и тригерите биха били най-добре сравнени, като се използва подход, подобен на този, който първоначално сте предложили. Други аспекти на дефиницията на схемата могат да бъдат добавени към горния скрипт.
  4. Дефинициите на FK по-горе идентифицират препращащите колони с външен ключ, но не и PK или таблицата, към която се препраща. Само още една подробност, която така и не успях да направя.

Дори и да не използвате скрипта. Има известно техническо удоволствие да си играеш с тези неща.;-)

Матю



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. BatchUpdateException:партидата няма да бъде прекратена

  2. merge update oracle не може да получи стабилен набор от редове

  3. PLS-00049 ЛОША ПРОМЕНЛИВА ЗА СВЪРЗВАНЕ

  4. Как да генерирате диаграма за връзка между обекти (ER) с помощта на Oracle SQL Developer

  5. Таблови пространства в Oracle