Et skemasammenligningsværktøj er en god idé. Databaseskemaet er langt mere kompliceret, end de fleste giver kredit, og enhver forskel mellem to databaseskemaer har potentiale til at forårsage fejl.
Hvis du stadig er ivrig efter at gøre det selv, er den bedste fremgangsmåde, jeg har fundet, at udtrække skemadefinitionerne til tekst og derefter køre en tekstsammenligning. Så længe alt er sorteret alfabetisk, kan du bruge funktionen Sammenlign dokumenter i Microsoft Word (eller FC.EXE, DIFF eller tilsvarende) for at fremhæve forskellene.
Følgende SQLPlus-script udlæser skemadefinitionen alfabetisk for at tillade sammenligning. Der er to sektioner. Den første sektion viser hver kolonne i formatet:
tabelnavn.kolonnenavn:datatype =data_standard
Det andet afsnit viser indekser og begrænsninger som følger:
PK constraint_name på tabelnavn (pk_column_list)FK constraint_name på tabelnavn (fk_column_list)CHECK constraint_name på tabelnavn (constraint_definition)
Scriptet tjener som en nyttig reference til at udtrække nogle af Oracle-skemadetaljerne. Dette kan være god viden at have, når du er ude på klientwebsteder, og du ikke har dine sædvanlige værktøjer til rådighed, eller når sikkerhedspolitikker forhindrer dig i at få adgang til en klientwebstedsdatabase direkte fra din egen pc.
sæt serveroutput til;sæt serveroutput til størrelse 1000000;erklær rowcnt pls_integer :=0; cursor c_column er 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_ ejer ='BCC' rækkefølge efter tabelnavn, kolonnenavn; cursor c_constraint er vælg 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, (vælg ejer, tabelnavn, 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 ) ) komma_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 ) ) komma_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 hvor c.owner ='BCC' og c.generated !='GENERATED NAME' og cc.owner =c.owner og cc.table_name =c.table_name og cc.constraint_name =c.constraint_name rækkefølge efter c.table_name, decode(c.constraint_type, 'P','PK', 'R','FK', 'C ','CHECK', c.constraint_type) desc, c.constraint_name;begynd for c_columnRow i 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; endeløkke; for c_constraintRow i c_constraint-løkke dbms_output.put_line(substr(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' på '|| c_constraintRow.table_name||' ('|| c_constraintRow.se|c_constraintRow.se|c_constraintRow.se| ') ',1.255)); hvis length(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' på '|| c_constraintRow.table_name||' ('|| c_constraintRow.search_condition|| c_constraintRow.r_columns||') out så d>b2_5 .put_line('... '||substr(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' på '|| c_constraintRow.table_name||' ('|| c_constraintRow.search_condition|| c_constraintRowns.r_columns.r_columns. |') ',256,251)); Afslut Hvis; rowcnt :=rowcnt + 1; end loop;end;/
Desværre er der et par begrænsninger:
- Indlejrede vognretur og hvidt mellemrum i data_defaults og kontrolbegrænsningsdefinitioner kan fremhæves som forskelle, selvom de har ingen effekt på skemaet.
- Indeholder ikke alternative nøgler, unikke indekser eller ydeevneindekser. Dette ville kræve en tredje SELECT-sætning i scriptet, der refererer til all_ind_columns og all_indexes katalogvisninger.
- Indeholder ikke sikkerhedsoplysninger, synonymer, pakker, udløsere osv. Pakker og udløsere ville bedst sammenlignes ved at bruge en fremgangsmåde, der ligner den, du oprindeligt foreslog. Andre aspekter af skemadefinitionen kunne føjes til ovenstående script.
- FK-definitionerne ovenfor identificerer de refererende fremmednøglekolonner, men ikke den PK eller den tabel, der henvises til. Bare en detalje mere, jeg aldrig nåede at gøre.
Også selvom du ikke bruger scriptet. Der er en vis teknisk fornøjelse ved at lege med det her.;-)
Matthew