2011-09-27 19 views
12

Tabloda yeni bir satır oluşturmaya çalışıyorum. Tabloda iki kısıtlama vardır - bir tanesi anahtar alan (DB_ID), diğeri ise ENV alanının birkaçından biri olacak şekilde bir değeri kısıtlar. Ben bir ekleme yaptığınızda, ben eklemek çalışıyorum alanlardan biri olarak anahtar alanını kapsar, ama ben bu hatayı alıyorum yoktur: BuradaEkleme sırasında benzersiz kısıtlama ihlali: neden? (Oracle)

unique constraint (N390.PK_DB_ID) violated 

hataya neden olan SQL var:

insert into cmdb_db 
    (narrative_name, db_name, db_type, schema, node, env, server_id, state, path) 
values 
    ('Test Database', 'DB', 'TYPE', 'SCH', '', 'SB01', 381, 'TEST', '') 

Dönebildiğim tek şey, Oracle'ın el ile satırlar eklendiyse, kullanılmakta olan bir DB_ID'yi atamaya çalışabilme olasılığıdır. Bu veritabanındaki veriler bir şekilde bir üretim veritabanından geri yüklendi/taşındı, ancak bunun nasıl yapıldığına dair ayrıntılarım yok.

Herhangi bir düşünce?

cevap

34

Tahminen, bu değer tabloda tanımlanan ekleme tetikleyici önce bir satır düzeyinde yaşadığı ediliyor. Bu tetikleyici, muhtemelen bir diziden değeri seçmektir. Veriler, üretim veritabanından (muhtemelen yakın zamanda) taşındığından beri, verdiğim veri, veriler kopyalandığında, dizi de değiştirilmeyecekti. Dizinin, şu anda hataya neden olan tabloda bulunan en büyük DB_ID'dan daha düşük değerler oluşturduğunu tahmin ediyorum.

Sanıyorum gibi, kullanılmakta olduğu sırası belirlemek için tetik bakarak ve bir

SELECT <<sequence name>>.nextval 
    FROM dual 

yapıyor ve

SELECT MAX(db_id) 
    FROM cmdb_db 

Eğer bu karşılaştırarak diziyi bu şüpheyi teyit olabilir

Veritabanında zaten var olan değerleri üretiyor, kullanılmayan değerler üretene kadar diziyi artırabilir ya da INCREMENT değerini çok büyük bir değere ayarlayabilir, nextvalı bir kez alabilir ve INCREMENT 1'e geri.

+9

+1 Mantıklı tahmin – APC

1

DB_ID birincil anahtar alanı için bir değer sağlamadığınız anlaşılıyor. Bu birincil anahtarsa, bu sütun için benzersiz bir değer sağlamanız gerekir. Bunu sağlamanın tek yolu, insert üzerinde, büyük olasılıkla bir diziden türetilen bir değer sağlayacak bir veritabanı tetikleyicisi yaratmak olacaktır.

Bu başka bir veritabanından bir geri yükleme işlemi ise ve bu yeni örnekte bir sıra varsa, bir değeri yeniden kullanmaya çalışıyor olabilir. Eski verilerin 1 - 1000 arasında benzersiz anahtarları varsa ve mevcut diziniz 500 olduğunda, zaten var olan değerler üretecektir. Bu tablo için bir sıra varsa ve onu kullanmaya çalışıyorsa, tablonuzdaki değerleri dizinin geçerli değeriyle eşitlemeniz gerekir.

Sen (tabii varsa) Eğer DB zaten varolan birincil anahtar çoğaltma gibi

+0

Veritabanındaki bilgilerim, yeni bir satır eklendiğinde anahtarın otomatik olarak oluşturulması gerektiğini söylüyor - bu yüzden DB_ID için değer sağlamadım. Ayrıca, aynı teknik, veritabanında benzer olan diğer tablolarda da çalışır; bunlar otomatik olarak oluşturulmuş bir kimlik anahtarına sahiptir. – Sean

+0

Yeni ortamda gerekli tetikleyicilerin/dizilerin var olup olmadığını görmek için veri sözlüğünü sorgulayabiliyor musunuz? Belki de her şey eski çevreden karşı karşıya değildi. –

1

Sizin hata görünüyor dizinin şimdiki değerini görmek için SEQUENCE_NAME.CURRVAL kullanabilirsiniz. IDENTITY anahtar sözcüğü gibi bir şeyi kullanarak kendi birincil anahtarını uygulamak için sql kodunuzu değiştirmelisiniz. Eğer DB_ID sütun için bir değer sağlayarak değiliz beri

CREATE TABLE [DB] (
    [DBId] bigint NOT NULL IDENTITY, 
    ... 

    CONSTRAINT [DB_PK] PRIMARY KEY ([DB] ASC), 

); 
+1

IDENTITY, Oracle'da geçerli bir anahtar kelime değil. –

+0

Bu, Oracle –

+1

için geçersiz bir ifadedir. Siz, efendim, haklısınız. Çözümüm SQL'de değil Oracle'da çalışıyor. Eğer SQL'in kimliğini Oracle'da çoğaltmak istiyorsanız, dizileri kullanmak isteyeceksiniz [link] (http://www.techonthenet.com/oracle/sequences.php) @Justin_Cave cevabında iyi bir uygulama var. –