2013-11-22 8 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-d-know-the-t-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);

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

바로 가기가 유혹 :

3

수퍼 유저 권한신속하고 더러운 방법 있습니다. 그러나 이것을 망치면 시스템이 깨질 수 있습니다.
기본 규칙은 다음과 같습니다. 시스템 카탈로그를 직접 변경하지 마십시오. (이 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]