2013-11-22 23 views
25

Bir seferde tüm NOT NULL kısıtlamalarını bir tablodan düşürmek mümkün müdür?Bir PostgreSQL tablosundan bir NOT NULL kısıtlaması bir seferde nasıl kaldırılır

Çok fazla NOT NULL kısıtlaması olan büyük bir masa var ve bunları ayrı ayrı bırakmaktan daha hızlı bir çözüm arıyorum.

+0

Bu bağlantıları görmeyi deneyin, bunu gerçekleştirmenin bir yolunu bulmanızda yardımcı olabilir. http://stackoverflow.com/questions/3370159/how-to-remove-not-null-constraint-in-sql-server-using-query http://stackoverflow.com/questions/2540615/how-can-i -in-bir-null-kısıtlama-in-oracle-ne-i-dont-know-the-t- –

cevap

47

yapabilirsiniz grup hepsini: Eğer gerekli oluşturmak için bir do block yazmak gibi hissediyorsan

alter table tbl alter col1 drop not null, 
       alter col2 drop not null, 
       … 

Ayrıca, katalogdan ilgili sütunların listesini alabilirsiniz sql. Örneğin, bir şey gibi: Bunu yaparsanız

select a.attname 
    from pg_catalog.pg_attribute a 
where attrelid = 'tbl'::regclass 
    and a.attnum > 0 
    and not a.attisdropped 
    and a.attnotnull; 

(. O filtrelemek isteyeceksiniz yüzden bu da birincil anahtar ilgili alanlarda içereceğini unutmayın)

, yapma Sütun adlarında potansiyel olarak tuhaf karakterlerle uğraşmanız gerektiğinde, quote_ident()'u kullanmayı unutmayın.

+1

Sorgunuz harika. Kataloğu hiç sorgulamadım. DO bloğu vermek bir sonraki adım olacaktır. – Stefan

0

Evet, öyle. Ben ..

.. Bütün plsql veritabanı geçilen ve tüm eşleşen kısıtlamaları kaldırılmış bir C# .net senaryo yazmaya zorunda kaldı

için

, tek kaldırmak için nasıl Belirli bir bilgiye gidermek için aynı sorunu vardı kısıtlamaları, bağlantıyı takip edin. Aynı alter açıklamada http://www.techonthenet.com/oracle/foreign_keys/drop.php

6

Eğer bu fonksiyonu kullanabilirsiniz PostreSQL tüm NOT NULL kısıtlamaları damla isterseniz:

CREATE OR REPLACE FUNCTION dropNull(varchar) RETURNS integer AS $$ 
DECLARE 
    columnName varchar(50); 
BEGIN 

    FOR columnName IN 

select a.attname 
    from pg_catalog.pg_attribute a 
where attrelid = $1::regclass 
    and a.attnum > 0 
    and not a.attisdropped 
    and a.attnotnull and a.attname not in(

    SELECT    
    pg_attribute.attname 
FROM pg_index, pg_class, pg_attribute 
WHERE 
    pg_class.oid = $1::regclass AND 
    indrelid = pg_class.oid AND 
    pg_attribute.attrelid = pg_class.oid AND 
    pg_attribute.attnum = any(pg_index.indkey) 
    AND indisprimary) 

      LOOP 
      EXECUTE 'ALTER TABLE ' || $1 ||' ALTER COLUMN '||columnName||' DROP NOT NULL';   
     END LOOP; 
    RAISE NOTICE 'Done removing the NOT NULL Constraints for TABLE: %', $1; 
    RETURN 1; 
END; 
$$ LANGUAGE plpgsql; 

birincil anahtarlar hariç tutulacak unutmayınız.

Sonra kullanarak çağırabilirsiniz:

SEÇ dropNull (tablename);

UPDATE pg_attribute 
SET attnotnull = FALSE 
WHERE attrelid = 'tbl_b'::regclass -- schema-qualify if needed! 
AND attnotnull 
AND NOT attisdropped 
AND attnum > 0; 

kısayol cazip:

3

superuser hakları ile hızlı ve kirli yolu yoktur. Ama eğer bunu düzeltirseniz, sisteminizi bozabilirsin.
Temel kural: sistem kataloglarına doğrudan müdahale etmeyiniz. (Bu what Denis already suggested uygulayan) bir DO açıklamada dinamik SQL ile bunu otomatikleştirmek:

temiz yolu sadece tablo değiştirmek için düzenli ayrıcalıkları ihtiyacı

DO 
$$ 
BEGIN 

EXECUTE (
    SELECT 'ALTER TABLE tbl_b ALTER ' 
     || string_agg (quote_ident(attname), ' DROP NOT NULL, ALTER ') 
     || ' DROP NOT NULL' 
    FROM pg_catalog.pg_attribute 
    WHERE attrelid = 'tbl_b'::regclass 
    AND attnotnull 
    AND NOT attisdropped 
    AND attnum > 0 
    ); 

END 
$$ 

Yine çok hızlı. Dinamik komutlarla bakımı gerçekleştirin ve SQL enjeksiyonuna karşı dikkatli olun.

Bu

bu büyük cevap bir spin-off: Orada
Generate DEFAULT values in a CTE UPSERT using PostgreSQL 9.3

biz ile oluşturulan bir tablodan NOT NULL kısıtlamaları düşmesi ihtiyacı var:

CREATE TABLE tbl_b (LIKE tbl_a INCLUDING DEFAULTS); 

per documentation yana:

Boş olmayan sınırlamalar her zaman yeni tabloya kopyalanır.

4

ALTER TABLE table_name ALTER COLUMN [SET NOT NULL | BOŞALTINIZ NULL]