2013-11-22 12 views
25

テーブルからすべてのNOT NULL制約を一度に削除できますか?PostgreSQLのテーブルからすべてのNOT NULL制約を一度に削除する方法

私は多くのNOT NULL制約を持つ大きなテーブルを持っており、私はそれを別々にドロップするよりも速いソリューションを探しています。

+0

これらのリンクを参考にすれば、この実装方法を理解するのに役立ちます。 http://stackoverflow.com/questions/3370159/how-to-remove-not-null-constraint-in-sql-server-using-query http://stackoverflow.com/questions/2540615/how-can-i -drop-a-not-null-constraint-in-oracle-when-i-dont-know-of-t –

答えて

47

することができますグループそれらすべてを:あなたが必要な生成するdo blockを書くように感じる場合

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

ます。また、カタログから関連する列のリストを取得することができますSQL。例えば、何かのように:あなたがこれを行う場合は

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

(。あなたがそれらをフィルタリングしたいと思うので、これは、あまりにも主キー関連のフィールドが含まれることに注意してください)

、しないでくださいカラム名に潜在的に奇妙な文字を扱う必要がある場合は、quote_ident()を使用することを忘れないでください。

+1

あなたの質問は素晴らしいです。私はカタログを尋ねたことはありません。 DOブロックを試すことは私の次のステップになります。 – Stefan

0

はい、そうです。私は単一を削除する方法についての具体的な情報については、

..解決するには...

を同じ問題を持っていた、私はすべてのPLSQLデータベースを横断し、一致するすべての制約を取り除いのC#.NETのスクリプトを記述する必要がありました制約、plはリンクに従います。同じALTER文でhttp://www.techonthenet.com/oracle/foreign_keys/drop.php

6

あなたはこの機能を使用することができますPostreSQL内のすべてのNOT NULL制約を削除したい場合:

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; 

主キーは除外されますのでご注意ください。

次に、あなたが使用してそれを呼び出すことができます。

SELECT dropNull(TABLENAME)。

3

迅速かつ汚い方法スーパーユーザ権限であり:ショートカットが魅力的です

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

。しかし、あなたがこれを台無しにすると、あなたのシステムを壊すかもしれません。
基本ルールは、システムカタログを直接改ざんすることはありません。 (これはwhat Denis already suggestedを実装)DO文での動的SQLとそれを自動化:

きれいな方法は、テーブルを変更するために、定期的な権限にを必要と

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 
$$ 

をまだ非常に速いです。動的コマンドで注意を払い、SQLインジェクションに注意してください。

これは、この大きな答えからのスピンオフである:あり
Generate DEFAULT values in a CTE UPSERT using PostgreSQL 9.3

我々が作成されたテーブルからNOT NULL制約をドロップする必要があります。

CREATE TABLE tbl_b (LIKE tbl_a INCLUDING DEFAULTS); 

ので、per documentation

非NULL制約は常に新しいテーブルにコピーされます。

4

ALTER TABLE table_name ALTER COLUMN [SET NOT NULL | DROP NOT NULL]

関連する問題