एक स्कीमा तुलना उपकरण एक अच्छा विचार है। अधिकांश लोगों द्वारा क्रेडिट देने की तुलना में डेटाबेस स्कीमा कहीं अधिक जटिल है, और दो डेटाबेस स्कीमा के बीच प्रत्येक अंतर में बग पैदा करने की क्षमता है।
यदि आप अभी भी इसे स्वयं करने के इच्छुक हैं, तो मैंने जो सबसे अच्छा तरीका खोजा है, वह है पाठ में स्कीमा परिभाषाएँ निकालना, फिर एक पाठ तुलना चलाना। जब तक सब कुछ वर्णानुक्रम में क्रमबद्ध किया जाता है, तब तक आप अंतरों को उजागर करने के लिए 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;
/
दुर्भाग्य से, इसकी कुछ सीमाएँ हैं:
- डेटा_डिफॉल्ट्स में एंबेडेड कैरिज रिटर्न और व्हाइटस्पेस, और चेक बाधा परिभाषाओं को अंतर के रूप में हाइलाइट किया जा सकता है, भले ही स्कीमा पर उनका शून्य प्रभाव हो।
- वैकल्पिक कुंजी, अद्वितीय अनुक्रमणिका या प्रदर्शन अनुक्रमणिका शामिल नहीं है। इसके लिए स्क्रिप्ट में एक तीसरे SELECT स्टेटमेंट की आवश्यकता होगी, जो all_ind_columns और all_indexes कैटलॉग दृश्यों को संदर्भित करता है।
- इसमें सुरक्षा विवरण, समानार्थक शब्द, पैकेज, ट्रिगर आदि शामिल नहीं हैं। पैकेज और ट्रिगर आपके द्वारा मूल रूप से प्रस्तावित दृष्टिकोण के समान दृष्टिकोण का उपयोग करने की तुलना में सबसे अच्छा होगा। स्कीमा परिभाषा के अन्य पहलुओं को उपरोक्त स्क्रिप्ट में जोड़ा जा सकता है।
- उपरोक्त एफके परिभाषाएं संदर्भित विदेशी कुंजी कॉलम की पहचान करती हैं, लेकिन पीके या तालिका को संदर्भित नहीं करती हैं। बस एक और विवरण जो मैंने कभी नहीं किया।
भले ही आप स्क्रिप्ट का इस्तेमाल न करें। इस सामान के साथ खेलने में एक निश्चित तकनीकी खुशी है।;-)
मैथ्यू