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

16

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_UK1di kotak pencarian SQL Developer 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.)

Álvaro González
sumber
Mungkin itu dibuat sebagai jenis objek lain dan bukan kendala unik? Mungkin indeks unik ..
Marian
Bisakah penciptaan awal dijalankan dengan tanda kutip di sekitar nama tabel? Ini akan membuat case case sensitif. Jika demikian, Anda dapat menjatuhkan dengan kutipan dan kasus yang sama.
Adam Butler

Jawaban:

13

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. Lihat all_indexesuntuk melihat apakah ada indeks yang dipanggil A_DUP_CALLE_UK1dan coba dan cari tahu apakah itu digunakan oleh sesuatu yang lain sebelum Anda menjatuhkannya!

Jack mengatakan coba topanswers.xyz
sumber
Ini masalahnya. File dump yang dihasilkan oleh expperintah berisi CREATE UNIQUE INDEX "A_DUP_CALLE_UK1" ...pernyataan yang tidak ada di set skrip asli.
Álvaro González
6

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 untuk menjatuhkan meja sepenuhnya menggunakan DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTSuntuk menyingkirkan segala sesuatu yang menjadi milik tabel itu dan kemudian membuat ulang 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.

seekor kuda tanpa nama
sumber
4

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;
Cristian Meneses A
sumber
db yang mana? termasuk tidak bekerja di oracle
Derick
1

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 lihat OBJECT_TYPEadalah INDEX.

Begitu juga keduanya:

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

Melakukan hal ini

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

Itu akan berhasil.

GAMBAR: masukkan deskripsi gambar di sini

Sachin
sumber
Tidak, itu tidak akan berhasil. Pernyataan Anda persis sama dengan pernyataan pertama dalam pertanyaan:ALTER TABLE A_DUP_CALLE DROP CONSTRAINT A_DUP_CALLE_UK1;
a_horse_with_no_name
Sebenarnya BEKERJA. Saya mengalami masalah yang sama sejak hari ini siang, dan mencari solusi saya menemukan ini. Terkadang CONSTRAINTS mungkin dibuat dengan cara case-sensitive, dalam hal ini, Anda harus memasukkan nama kendala dalam tanda kutip ganda ketika Anda menjatuhkannya.
Sachin
Dan itu berhasil untuk saya. Saya tidak menyebutkan batasan secara eksplisit, sehingga sistem memberikannya nama yang dihasilkan sendiri Relationship142dan NOT NULLkendala lainnya diberi nama SYS_C0015910. Jadi SYS_C0015910berhasil dihapus dengan permintaan ALTER sederhana, tetapi Relationship142membutuhkan QUOTES QUUBES
Sachin
1
Anda membuat batasan menggunakan tanda kutip ganda, misalnya: alter table ... add constraint "Relationship143" ... "Relationship143"memang nama yang berbeda dari RELATIONSHIP143. Tapi "RELATIONSHIP143"dan RELATIONSHIP143yang identik
a_horse_with_no_name
2
Oracle (database) tidak akan pernah membuat nama seperti "Relationship143"itu sendiri. Mungkin salah satu alat Anda yang melakukan ini. Pokoknya: sebagaimana adanya, jawaban Anda benar-benar salah dalam konteks pertanyaan awal.
a_horse_with_no_name