Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Bandingkan dua skema dan perbarui skema lama dengan kolom baru skema baru

Alat perbandingan skema adalah ide yang bagus. Skema database jauh lebih rumit daripada yang diberikan kebanyakan orang, dan setiap perbedaan antara dua skema database berpotensi menyebabkan bug.

Jika Anda masih ingin melakukannya sendiri, pendekatan terbaik yang saya temukan adalah mengekstrak definisi skema ke teks, lalu menjalankan perbandingan teks. Selama semuanya diurutkan berdasarkan abjad, Anda kemudian dapat menggunakan fitur Bandingkan Dokumen di Microsoft Word (atau FC.EXE, DIFF atau yang setara), untuk menyoroti perbedaannya.

Skrip SQLPlus berikut mengeluarkan definisi skema menurut abjad, untuk memungkinkan perbandingan. Ada dua bagian. Bagian pertama mencantumkan setiap kolom, dalam format:

table_name.column_name: data_type = data_default <nullable>

Bagian kedua mencantumkan indeks dan batasan, sebagai berikut:

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)

Script berfungsi sebagai referensi yang berguna untuk mengekstrak beberapa detail skema Oracle. Ini bisa menjadi pengetahuan yang baik untuk dimiliki ketika Anda berada di luar situs klien dan Anda tidak memiliki alat yang biasa tersedia, atau ketika kebijakan keamanan mencegah Anda mengakses database situs klien langsung dari PC Anda sendiri.

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

Sayangnya, ada beberapa batasan:

  1. Kembali carriage yang disematkan dan spasi kosong di data_defaults, dan periksa definisi batasan, dapat disorot sebagai perbedaan, meskipun tidak ada pengaruhnya pada skema.
  2. Tidak termasuk kunci alternatif, indeks unik, atau indeks kinerja. Ini akan membutuhkan pernyataan SELECT ketiga dalam skrip, yang merujuk tampilan katalog all_ind_columns dan all_indexes.
  3. Tidak termasuk detail keamanan, sinonim, paket, pemicu, dll. Paket dan pemicu akan lebih baik dibandingkan menggunakan pendekatan yang serupa dengan yang Anda usulkan sebelumnya. Aspek lain dari definisi skema dapat ditambahkan ke skrip di atas.
  4. Definisi FK di atas mengidentifikasi kolom kunci asing yang merujuk, tetapi bukan PK atau tabel yang dirujuk. Hanya satu detail lagi yang tidak pernah saya lakukan.

Bahkan jika Anda tidak menggunakan skrip. Ada kesenangan teknisi tertentu dalam bermain dengan barang ini.;-)

Matius



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle - Mengapa saya harus menggunakan paket daripada prosedur atau fungsi yang berdiri sendiri?

  2. Mengulang nilai, membuat kueri dinamis, dan menambahkan ke kumpulan hasil

  3. Oracle SQL:Menerima kesalahan 'tidak ada kunci unik atau kunci utama yang cocok' dan tidak tahu mengapa

  4. Bagaimana cara menggunakan perbedaan dan penjumlahan keduanya di Oracle?

  5. Bisakah saya mengubah baris tanggal menjadi kolom tanpa harus menentukan tanggal di pivot? Oracle SQL