模式比較工具是一個好主意。數據庫模式比大多數人所稱讚的要複雜得多,並且兩個數據庫模式之間的每個差異都有可能導致錯誤。
如果您仍然熱衷於自己做,我發現的最好方法是將模式定義提取到文本,然後運行文本比較。只要所有內容按字母順序排序,就可以使用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模式的一個有益的參考細節。當您離開客戶站點並且沒有可用的常用工具時,或者安全策略阻止您直接從您自己的PC訪問客戶端站點數據庫時,這可能是非常好的知識。
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;
/
不幸的是,有一些限制:
- 嵌入式回車和空格在data_defaults,檢查約束定義,也應當強調的差異,即使他們在架構零效果。
- 不包含備用密鑰,唯一索引或性能指標。這將需要腳本中的第三個SELECT語句,引用all_ind_columns和all_indexes目錄視圖。
- 不包括安全細節,同義詞,軟件包,觸發器等。使用與您最初提議的方法相似的方法可以最好地比較軟件包和觸發器。模式定義的其他方面可以添加到上面的腳本中。
- 上面的FK定義標識引用外鍵列,但不標識PK或被引用的表。只是我從來沒有做過的更多細節。
即使你不使用腳本。玩這個東西有一定的技術高興。 ;-)
馬修
小心,你的查詢將返回在'SCHEMA_1'新列,但你沒有得到中存在的'SCHEMA_2'但不是在'SCHEMA_1'列。而且你沒有發現已經改變的列。祝你好運:) – 2010-02-25 08:39:58
感謝Peter Lang ..我知道我不是甲骨文的專家:)如果有人有一些想法如何做到這一點。請與我分享.... – coder247 2010-02-25 08:44:35
您的新模式是否包含數據?是刪除並重新創建表的一個選項?你有幾張桌子?你只改變了列,還是有新的表格? – 2010-02-25 08:45:45