Cara mengambil data batasan kunci asing

9

Saya mencari kueri yang memungkinkan untuk mengambil info kunci asing (setiap baris: tabel & bidang referensi, tabel & bidang referensi) dari seluruh skema.

Saya telah menemukan ini, tetapi tidak memberikan semua informasi yang saya butuhkan: /programming/4389228/sql-for-oracle-to-check-if-a-constraint-exists

Saat ini saya sedang mengerjakannya dan mungkin berakhir dengan solusi di menit / jam berikutnya. Tetapi jika seseorang sudah memiliki solusi kerja penuh, saya akan senang mengetahuinya :)

Frosty Z
sumber
Untuk Pengembang SQL, Anda dapat menemukan info ini dalam format ERD di tab 'Model' di atas meja (seperti yang dirujuk di sini . Tidak berguna untuk skrip, tetapi jika Anda hanya memerlukan info dan mendarat di sini seperti yang saya lakukan, itu mungkin saja membantu
SnoringFrog

Jawaban:

12

Setelah beberapa "rekayasa balik" pada kueri yang dibuat oleh alat Navicat saat membuka jendela desain meja untuk sebuah tabel (kueri mengambil info tentang kunci asing muncul di jendela sejarah ), berikut adalah solusinya:

SELECT
    CONS.CONSTRAINT_NAME,
    CONS.TABLE_NAME,
    COLS.COLUMN_NAME,
    CONS.R_CONSTRAINT_NAME,
    CONS_R.TABLE_NAME R_TABLE_NAME,
    COLS_R.COLUMN_NAME R_COLUMN_NAME

FROM USER_CONSTRAINTS CONS
    LEFT JOIN USER_CONS_COLUMNS COLS ON COLS.CONSTRAINT_NAME = CONS.CONSTRAINT_NAME
    LEFT JOIN USER_CONSTRAINTS CONS_R ON CONS_R.CONSTRAINT_NAME = CONS.R_CONSTRAINT_NAME
    LEFT JOIN USER_CONS_COLUMNS COLS_R ON COLS_R.CONSTRAINT_NAME = CONS.R_CONSTRAINT_NAME

-- returns only foreign key constraints
WHERE CONS.CONSTRAINT_TYPE = 'R'

ORDER BY CONS.TABLE_NAME, COLS.COLUMN_NAME
Frosty Z
sumber
2

Pengembang SQL dikirimkan dengan laporan yang melakukan hal ini.

Itu melakukannya untuk skema login saja, tetapi ini adalah perbaikan cepat untuk membuatnya mendapatkan setiap FK dalam database - meskipun Anda mungkin ingin menghilangkan skema seperti 'APEX ...' dan 'SYS.'

Ini juga menghilangkan hal-hal seperti, tabel di tempat sampah.

Laporan asli ada di panel Laporan, di laporan kamus data.

Inilah permintaan yang diubah untuk mendapatkan SEMUA FK.

    SELECT
    c.owner "Owner",
    c.table_name "Table_Name",
    c.constraint_name "Constraint_Name",
    c.delete_rule "Delete_Rule",
    d.columns,
    c.r_owner "Owner of Related Table",
    (
        SELECT
            r.table_name
        FROM
            sys.all_constraints r
        WHERE
            c.r_owner = r.owner
        AND
            c.r_constraint_name = r.constraint_name
    ) "Related Table",
    c.r_constraint_name "Related Constraint"
FROM
    sys.all_constraints c,
    (
        SELECT
            a.owner,
            a.table_name,
            a.constraint_name,
            MAX(
                DECODE(position,1,substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,2,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,3,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,4,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,5,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,6,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,7,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,8,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,9,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,10,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,11,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,12,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,13,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,14,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,15,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,16,','
                 ||  substr(column_name,1,30),NULL)
            ) columns
        FROM
            sys.all_constraints a,
            sys.all_cons_columns b
        WHERE
            a.constraint_name = b.constraint_name
        AND
            a.owner = b.owner
        AND
            a.constraint_type = 'R'
        AND
            substr(a.table_name,1,4) != 'BIN$'
        AND
            substr(a.table_name,1,3) != 'DR$'
        AND (
                :table_name IS NULL
            OR
                instr(upper(a.table_name),upper(:table_name) ) > 0
        ) GROUP BY
            a.owner,
            a.table_name,
            a.constraint_name
    ) d
WHERE
    c.owner = d.owner
AND
    c.table_name = d.table_name
AND
    c.constraint_name = d.constraint_name
ORDER BY
    c.owner,
    c.table_name,
    c.constraint_name

Dan inilah laporannya.

masukkan deskripsi gambar di sini

tukang itu
sumber
1

Sedikit kode rumit yang juga membuang komentar pada cols (berdasarkan kode Frosty):

SELECT
    dt.table_name, dt.column_name, dt.data_type, dt.data_length,
    constr.r_tbl r_table, constr.r_col r_column,
    comm.comments
  FROM user_col_comments comm, user_tab_columns dt
  LEFT OUTER JOIN (
    SELECT
      cons.table_name tbl,
      cols.column_name col,
      cons_r.table_name r_tbl,
      cols_r.column_name r_col
    FROM user_constraints cons
      LEFT JOIN user_cons_columns cols ON cols.constraint_name = cons.constraint_name
      LEFT JOIN user_constraints cons_r ON cons_r.constraint_name = cons.r_constraint_name
      LEFT JOIN user_cons_columns cols_r ON cols_r.constraint_name = cons.r_constraint_name
    WHERE cons.constraint_type = 'R'
    ) constr ON constr.tbl = dt.table_name AND constr.col = dt.column_name
  WHERE dt.table_name = comm.table_name
    AND dt.column_name = comm.column_name
  ORDER BY dt.table_name, dt.column_name
  ;

Untuk membuat output saya menggunakan lebih mudah dibaca break on TABLE_NAME;di sqlplus(lihat pertanyaan saya /programming/14998296/print-only-first-unique-value-for-column-that-order-by-in-oracle-sqlplus / ).

UPDATE Permintaan yang lebih sederhana yang mengumpulkan daftar tabel yang memiliki referensi FK ke tabel yang diberikan (berguna jika Anda ingin membersihkan kendala setelah mengganti nama tabel):

select * from SYS.USER_CONSTRAINTS cons
  join SYS.USER_CONSTRAINTS rcons on rcons.CONSTRAINT_NAME = cons.R_CONSTRAINT_NAME
  where cons.CONSTRAINT_TYPE = 'R' and rcons.TABLE_NAME 'TBL_NAME';

select * from SYS.USER_CONSTRAINTS cons
  join SYS.USER_CONSTRAINTS rcons on rcons.CONSTRAINT_NAME = cons.R_CONSTRAINT_NAME
  where cons.CONSTRAINT_TYPE = 'R' and rcons.TABLE_NAME like '%/_OLD' escape '/';
gavenkoa
sumber