Kısıtlamanın adını bilmediğim halde Oracle'da "boş olmayan" bir kısıtlamayı nasıl kaldırabilirim?


85

Bir alanda NOT NULL kısıtlaması olan bir veritabanım var ve bu kısıtlamayı kaldırmak istiyorum. Karmaşıklaştıran faktör, bu kısıtlamanın sistem tanımlı bir ada sahip olması ve bu kısıtlamanın adının üretim sunucusu, bütünleştirme sunucusu ve çeşitli geliştirici veritabanları arasında farklılık göstermesidir. Mevcut sürecimiz değişiklik betiklerini kontrol etmektir ve otomatik bir görev, hedef veritabanına karşı sqlplus aracılığıyla uygun sorguları yürütür, bu nedenle doğrudan sqlplus'a gönderilebilecek bir çözümü tercih ederim.

Kendi veritabanımda, bunu bırakacak SQL:

alter table MYTABLE drop constraint SYS_C0044566

all_constraintsGörünümü sorguladığımda kısıtlamayı görebiliyorum:

select * from all_constraints where table_name = 'MYTABLE'

ancak SEARCH_CONDITION'ın LONGveri türüyle nasıl çalışacağımdan veya aranan kısıtlamayı adını bildikten sonra bile dinamik olarak en iyi nasıl sileceğimden emin değilim .

Öyleyse, bu kısıtlamayı adından ziyade ne olduğuna bağlı olarak kaldırabilecek bir değişiklik komut dosyasını nasıl oluşturabilirim?


DÜZENLEME: @ Allan'ın cevabı iyi bir cevap, ancak (Oracle uzmanlığımdan yoksun olduğum için) sistem tarafından oluşturulmuş bir ada sahip olabilecek herhangi bir kısıtlamanın onunla ilişkilendirilmiş olabileceği evrensel olarak doğru olmayabilir adını bilmek zorunda kalmadan kısıtlama. Bu kısıtlamayı mantıksal olarak kaldırırken sistem tarafından adlandırılan bir kısıtın adını bilmek zorunda kalmamak için her zaman bir yol olacağı doğru mu?


3
Sadece merakınızı gidermek için: NOT NULL kısıtlaması, Oracle'daki kısıtlamanın adını bilmenize gerek kalmadan kaldırabileceğiniz tek kısıt türüdür. Kısıtlamanın adını bilmeniz gereken diğer tüm kısıtlama türleri.
Jeffrey Kemp

Yanıtlar:


170
alter table MYTABLE modify (MYCOLUMN null);

Oracle'da, bir sütun için null belirtilmediğinde boş sınırlamalar otomatik olarak oluşturulmaz. Aynı şekilde, sütun boş değerlere izin verecek şekilde değiştirildiğinde otomatik olarak bırakılırlar.

Gözden geçirilmiş sorunun netleştirilmesi : Bu çözüm yalnızca "boş olmayan" sütunlar için oluşturulan kısıtlamalar için geçerlidir. Sütun tanımında adlandırmadan "Birincil Anahtar" veya bir kontrol kısıtlaması belirtirseniz, kısıtlama için sistem tarafından oluşturulan bir ad (ve birincil anahtar için dizin) elde edersiniz. Bu gibi durumlarda, bırakmak için adını bilmeniz gerekir. Buradaki en iyi tavsiye, "boş değil" dışındaki tüm kısıtlamalar için bir ad belirlediğinizden emin olarak senaryodan kaçınmaktır. Kendinizi bu kısıtlamalardan birini genel olarak kaldırmanız gereken bir durumda bulursanız, muhtemelen PL / SQL ve veri tanımlama tablolarına başvurmanız gerekecektir.


Bu gerçek olamayacak kadar iyi görünüyor, ancak kesinlikle mevcut durumumu ele alıyor ve açıkça basit! Oracle'da kısıt adının sistem tarafından oluşturulabildiği, ancak bunun gibi kısıtlama adından kaçınmak için sql'nin yazılamadığı durumlar var mı?
Chris Farmer

1
Teşekkürler ... Görünüşe not nullgöre, şemamda beni bu şekilde etkileyebilecek tek sistem adı kısıtlamalar.
Chris Farmer

16

Deneyin:

alter table <your table> modify <column name> null;

1

Unutmayın, null yapılabilir yapmak istediğiniz alan birincil anahtarın parçasıysa, yapamazsınız. Birincil Anahtarlar boş alanlara sahip olamaz.


1

Kullanılan kısıtlamaları keşfetmek için aşağıdaki kodu kullanın:

-- Set the long data type for display purposes to 500000.

SET LONG 500000

-- Define a session scope variable.

VARIABLE output CLOB

-- Query the table definition through the <code>DBMS_METADATA</code> package.

SELECT dbms_metadata.get_ddl('TABLE','[Table Described]') INTO :output FROM dual;

Bu, esasen başvurulan tablonun nasıl yapıldığına dair bir oluşturma ifadesini gösterir. Tablonun nasıl oluşturulduğunu bilerek, tüm tablo kısıtlamalarını görebilirsiniz.

Cevap Michael McLaughlin'in blogundan alınmıştır: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ Veritabanı Tasarımı I sınıfından.


0

Farklı değerlere izin vermek için güncellemem gereken özel bir kontrol kısıtlamasını aşmaya çalışırken aynı sorunla karşı karşıyaydım. Sorun, ALL_CONSTRAINTS'in kısıtlamaların hangi sütuna uygulandığını söylemenin bir yolu olmamasıdır. Bunu yapmayı başardığım yol, bunun yerine ALL_CONS_COLUMNS'yi sorgulamak, ardından her bir kısıtlamayı adlarına göre kaldırmak ve yeniden oluşturmaktı.

all_cons_columns'dan constraint_name'i seçin; burada table_name = [TABLE_NAME] ve column_name = [COLUMN_NAME];


0

Yapıların kopyalarını geçici tablolara yaptığımda bana böyle bir şey oldu, bu yüzden boş olmayanları kaldırdım.

DECLARE
   CURSOR cur_temp_not_null IS
        SELECT table_name, constraint_name  FROM all_constraints WHERE table_name LIKE 'TEMP_%' AND  owner='myUSUARIO';

   V_sql VARCHAR2(200); 

BEGIN
  FOR c_not_null IN cur_temp_not_null
   LOOP
     v_sql :='ALTER TABLE ' || c_not_null.table_name || ' DROP CONSTRAINT '|| c_not_null.constraint_name;
     EXECUTE IMMEDIATE  v_sql;     
  END LOOP;
END;

Stack Overflow, yalnızca İngilizce bir sitedir. Ancak, Stack Overflow en español var . Düzenlememe bakın.
help-info.de

0

Tablo yaratılırken bir isim olmadan STATUS sütununda kısıt oluşturulmuşsa, Oracle buna rastgele bir isim atayacaktır. Maalesef, kısıtlamayı doğrudan değiştiremiyoruz.

STATUS sütununa bağlı adsız kısıtlamanın kaldırılmasıyla ilgili adımlar

  1. STATUS alanını yeni bir STATUS2 alanına kopyala
  2. STATUS2'de KONTROL kısıtlamalarını tanımlayın
  3. STATUS'dan STATUS2'ye veri taşıma
  4. DURUM sütununu bırak
  5. STATUS2'yi STATUS olarak yeniden adlandırın

    ALTER TABLE MY_TABLE ADD STATUS2 NVARCHAR2(10) DEFAULT 'OPEN'; ALTER TABLE MY_TABLE ADD CONSTRAINT MY_TABLE_CHECK_STATUS CHECK (STATUS2 IN ('OPEN', 'CLOSED')); UPDATE MY_TABLE SET STATUS2 = STATUS; ALTER TABLE MY_TABLE DROP COLUMN STATUS; ALTER TABLE MY_TABLE RENAME COLUMN STATUS2 TO STATUS;

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.