it-swarm.asia

Tidak dapat menjatuhkan batasan yang tidak ada dan tidak bisa membuatnya juga

Saat menguji beberapa skrip migrasi dengan salinan data produksi (skrip berjalan baik dengan data pengembangan) saya menemukan situasi yang aneh. CONSTRAINT telah berubah jadi saya mengeluarkan perintah DROP + ADD:

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT A_DUP_CALLE_UK1;

ALTER TABLE A_DUP_CALLE
ADD CONSTRAINT A_DUP_CALLE_UK1 UNIQUE (
    CONTROL_ID,
    CALLE_AYTO_DUPL
)
ENABLE;

Perintah DROP bekerja dengan baik tetapi ADD satu gagal. Sekarang, saya menjadi lingkaran setan. Saya tidak dapat menghapus batasan karena tidak ada (penurunan awal berfungsi seperti yang diharapkan):

ORA-02443: Tidak dapat menjatuhkan batasan - tidak ada batasan

Dan saya tidak dapat membuatnya karena namanya sudah ada:

ORA-00955: nama sudah digunakan oleh objek yang ada

Saya mengetik A_DUP_CALLE_UK1 ke dalam kotak SQL Developer Cari dan ... ini dia! Pemilik, nama tabel, tablescape ... semuanya cocok: itu bukan objek yang berbeda dengan nama yang sama, itu adalah kendala asli saya. Tabel muncul dalam detail kendala tetapi kendala tidak muncul dalam detail tabel.

Pertanyaan saya:

  • Apa penjelasan untuk ini?
  • Bagaimana saya bisa memastikan itu tidak akan terjadi ketika saya melakukan peningkatan nyata di server langsung?

(Server 10g XE, saya tidak punya cukup reputasi untuk membuat tag.)

16

Pada tebakan saya akan mengatakan Marian benar dan ini disebabkan oleh indeks unik dan kendala memiliki nama yang sama, misalnya:

create table t( k1 integer, k2 integer, 
                constraint u1 unique(k1,k2) using index(create unique index u1 on t(k1,k2)),
                constraint u2 unique(k2,k1) using index u1);

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

alter table t drop constraint u1;

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

Biasanya ketika Anda menambahkan batasan unik, indeks unik dengan nama yang sama dibuat - tetapi indeks dan batasan bukanlah hal yang sama. Lihatlah all_indexes untuk melihat apakah ada indeks yang disebut A_DUP_CALLE_UK1 dan coba dan cari tahu apakah itu digunakan oleh sesuatu yang lain sebelum Anda menjatuhkannya!

Tampak sangat aneh.

Anda dapat menjalankan:

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

untuk memeriksa apakah objek apa yang dikeluhkan oleh Oracle. Kemudian Anda dapat menjalankan pernyataan DROP yang sesuai untuk itu.

Satu-satunya hal lain yang dapat saya pikirkan adalah menjatuhkan meja sepenuhnya menggunakan DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTS untuk menyingkirkan semua yang menjadi milik tabel itu dan kemudian membuatnya kembali sepenuhnya.

Jika tabel berisi data yang berharga, Anda dapat membuat cadangannya sebelumnya:

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

Setelah Anda membuat ulang tabel, Anda bisa melakukannya

INSERT INTO A_DUP_CALLE (col1, col2, col3) 
SELECT col1, col2, col3
FROM old_data

untuk mengembalikan data.

Saya memiliki masalah yang sama beberapa menit yang lalu ... dan saya telah menemukan penjelasan.

Dengan membuat Kunci Utama, Oracle menciptakan dua objek: batasan, dan indeks, yang mengontrol bagian "UNIK".

Dengan menjatuhkan batasan, indeks tetap di sana, menggunakan nama indeks yang sama, jadi jika Anda mengeksekusi saja

alter table t drop constraint u1;

Anda hanya akan menjatuhkan batasannya. Untuk menjatuhkan indeks, Anda harus menjalankan

drop index u1;

Ini harus melakukan pekerjaan. Atau, Anda bisa melakukan kedua perintah ini secara bersamaan dengan perintah tersebut

alter table t drop constraint u1 including indexes;
5

Kendala kunci primer disertai dengan indeks. Anda menjatuhkan batasan tetapi tidak mengindeks. Memeriksa:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

dan Anda melihat OBJECT_TYPE adalah INDEX.

Begitu juga keduanya:

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;
1
gavenkoa

Melakukan hal ini

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

Itu akan berhasil.

GAMBAR: enter image description here

1
Sachin