2013-11-22 7 views
25

Ist es möglich, alle NOT NULL-Einschränkungen aus einer Tabelle auf einmal zu löschen?Wie alle NOT NULL Constraints von einer PostgreSQL-Tabelle auf einmal gelöscht werden können

Ich habe eine große Tabelle mit vielen NOT NULL-Einschränkungen und ich suche nach einer Lösung, die schneller ist, als sie getrennt fallen zu lassen.

+0

Versuchen Sie, diese Links zu sehen, die Ihnen helfen können, einen Weg zu finden, dies zu implementieren. 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-wenn-ich-kenne-nicht-den-Namen-von-t –

Antwort

47

können Sie gruppieren sie alle in der gleichen Alter Aussage:

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

Sie können auch die Liste der relevanten Spalten aus dem Katalog abrufen, wenn Sie einen do block fühlen sich wie schreiben die benötigt erzeugen sql. Zum Beispiel so etwas wie:

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

(. Beachten Sie, dass dies die Primärschlüssel in verwandten Bereichen schließen, so dass Sie diejenigen heraus filtern, werden wollen)

Wenn Sie dies tun, nicht Vergessen Sie nicht, quote_ident() für den Fall zu verwenden, dass Sie sich mit möglicherweise seltsamen Zeichen in Spaltennamen beschäftigen müssen.

+1

Ihre Abfrage ist großartig. Ich habe den Katalog nie abgefragt. Einen DO-Block auszuprobieren, wird mein nächster Schritt sein. – Stefan

0

Ja, ist es. Ich hatte das gleiche Problem ..

zu beheben, ich hatte einen C# .NET-Skript zu schreiben, die alles PLSQL Datenbank durchlaufen und entfernt alle die passenden Einschränkungen ..

Für spezifische Informationen darüber, wie einzelne entfernen Einschränkungen, pl folgen Sie dem Link. http://www.techonthenet.com/oracle/foreign_keys/drop.php

6

Wenn Sie alle NOT NULL Einschränkungen fallen wollen in PostreSQL Sie diese Funktion nutzen zu können:

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; 

Bitte beachten Sie, dass die Primärschlüssel werden ausgeschlossen.

Dann rufen Sie können es mit:

SELECT dropNull (TABELLENNAME);

3

Es gibt einen quick and dirty Weg mit Superuser-Privilegien:

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

Die Verknüpfung verlockend ist. Aber wenn Sie dies vermasseln, können Sie am Ende Ihr System brechen.
Die Grundregel lautet: Manipulieren Sie niemals direkt Systemkataloge.

Die saubere Art und Weise muss nur regelmäßig Privilegien die Tabelle ändern: automatisieren sie mit dynamischem SQL in einer DO Anweisung (dies implementiert what Denis already suggested):

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

noch sehr schnell. Führen Sie die Pflege mit dynamischen Befehlen aus und beachten Sie die SQL-Injection.

Dies ist ein Spin-off von dieser größeren Antwort:
Generate DEFAULT values in a CTE UPSERT using PostgreSQL 9.3

Dort haben wir die Notwendigkeit NOT NULL Einschränkungen aus einer Tabelle mit erstellt fallen zu lassen:

CREATE TABLE tbl_b (LIKE tbl_a INCLUDING DEFAULTS); 

Da per documentation:

Not-Null-Bedingungen werden immer in die neue Tabelle kopiert.

4

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

Verwandte Themen