sql >> Database >  >> RDS >> Oracle

Vergelijk twee schema's en werk het oude schema bij met de nieuwe kolommen van het nieuwe schema

Een schemavergelijkingstool is een goed idee. Het databaseschema is veel gecompliceerder dan de meeste mensen toekennen, en elk verschil tussen twee databaseschema's kan bugs veroorzaken.

Als je het nog steeds graag zelf wilt doen, is de beste aanpak die ik heb gevonden om de schemadefinities naar tekst te extraheren en vervolgens een tekstvergelijking uit te voeren. Zolang alles alfabetisch is gesorteerd, kunt u de functie Documenten vergelijken in Microsoft Word (of FC.EXE, DIFF of gelijkwaardig) gebruiken om de verschillen te markeren.

Het volgende SQLPlus-script voert de schemadefinitie alfabetisch uit om vergelijking mogelijk te maken. Er zijn twee secties. De eerste sectie geeft een overzicht van elke kolom, in het formaat:

table_name.column_name: data_type = data_default <nullable>

In het tweede gedeelte worden indexen en beperkingen als volgt opgesomd:

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)

Het script dient als nuttige referentie voor het extraheren van enkele details van het Oracle-schema. Dit kan een goede kennis zijn wanneer u zich op klantensites bevindt en u niet over uw gebruikelijke tools beschikt, of wanneer het beveiligingsbeleid u verhindert om rechtstreeks vanaf uw eigen pc toegang te krijgen tot een database van een clientsite.

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;
/

Helaas zijn er een paar beperkingen:

  1. Ingesloten regelterugloop en witruimte in data_defaults en controlebeperkingsdefinities kunnen worden gemarkeerd als verschillen, ook al hebben ze geen effect op het schema.
  2. Omvat geen alternatieve sleutels, unieke indexen of prestatie-indexen. Hiervoor is een derde SELECT-instructie in het script vereist, die verwijst naar de catalogusweergaven all_ind_columns en all_indexes.
  3. Bevat geen beveiligingsdetails, synoniemen, pakketten, triggers, enz. Pakketten en triggers kunnen het beste worden vergeleken met een benadering die vergelijkbaar is met degene die u oorspronkelijk voorstelde. Andere aspecten van de schemadefinitie kunnen aan het bovenstaande script worden toegevoegd.
  4. De FK-definities hierboven identificeren de refererende refererende-sleutelkolommen, maar niet de PK of de tabel waarnaar wordt verwezen. Nog een detail waar ik nooit aan toegekomen ben.

Ook als je het script niet gebruikt. Er is een zeker technisch plezier in het spelen met dit spul.;-)

Matthew



  1. MySQL-query om klanten te vinden die twee specifieke producten hebben besteld

  2. 11 manieren om externe sleutels in een SQL Server-database te retourneren met T-SQL

  3. Hoe kan ik zien welke transactie een vergrendelingsstatus Wachten op tabelmetagegevens veroorzaakt?

  4. VERWIJDER alles waar de beperking van de MySQL-externe sleutel niet faalt