2010-11-10 8 views
5

Mam tabelę PostgreSQL z kilkoma kolumnami boolowskimi, obecnie zawierającą tylko wartość true lub null. Chcę wykonać następujące czynności dla nich wszystkich:PostgreSQL: jak skutecznie zmienić wiele kolumn z psql?

  1. Dodaj domyślną wartość fałszywą
  2. zmienić wszystkie wartości null na false
  3. Dodaj not null ograniczenie

tj .:

-- for each column specified: 
update my_table set my_column = 'f' where my_column is null; 
alter table my_table alter column my_column set default 'f'; 
alter table my_table alter column my_column set not null; 

Czy istnieje funkcja psql (lub standardowego SQL), która będzie iterować na określonej liście kolumn i zastosować sekwencję operacji do każdego z nich?

Odpowiedz

4

Będzie to zrobić, musi w wersji 8.4 lub wyższej ze względu na o zmiennej liczbie argumentów.

CREATE OR REPLACE FUNCTION setdefaults(
    IN _tname TEXT,  -- tablename to alter 
    VARIADIC _cname TEXT[] -- all columnnames to alter 
) 
RETURNS boolean 
LANGUAGE plpgsql 
AS 
$$ 
DECLARE 
    row record; 
BEGIN 
    FOR row IN SELECT unnest(_cname) AS colname LOOP 
     EXECUTE 'ALTER TABLE ' || quote_ident(_tname) || ' ALTER COLUMN ' || quote_ident(row.colname) || ' SET DEFAULT false;'; 
     EXECUTE 'UPDATE ' || quote_ident(_tname) || ' SET ' || quote_ident(row.colname) || ' = DEFAULT WHERE ' || quote_ident(row.colname) || ' IS NULL;'; 
     EXECUTE 'ALTER TABLE ' || quote_ident(_tname) || ' ALTER COLUMN ' || quote_ident(row.colname) || ' SET NOT NULL;'; 
    END LOOP; 

    RETURN TRUE; 
END; 
$$; 

SELECT setdefaults('foo', 'x','y','z'); -- alter table "foo" 
+0

Świetne, dziękuję! Ten jeden kawałek kodu jest pełen przydatnych rzeczy, o których nie wiedziałem. –

9

Nie można wykonywać iteracji po wszystkich kolumnach, ale aby być pewnym, że i tak nie chcemy tego robić, należy określić, które z nich należy zmienić. Innym sposobem byłoby wykonanie skryptu zapytującego o nazwy kolumn, a następnie ich zmianę.

Aby je zmienić, należy użyć ALTER TABLE. Zobacz doc PgSQL: http://www.postgresql.org/docs/8.4/static/sql-altertable.html

ALTER TABLE xy ALTER COLUMN a SET DEFAULT FALSE, ALTER COLUMN b SET NOT NULL 

itp

+1

Dzięki. Wiem, jak to zrobić ręcznie, ale właśnie zastanawiałem się, czy istnieje narzędzie do iteracji. Będę edytować, aby uczynić to jaśniejszym :) Również konieczne jest zaktualizowanie wartości null do wartości false przed ustawieniem 'not null' else otrzymasz błąd; ustawienie wartości domyślnej nie powoduje automatycznej konwersji po dodaniu 'not null'. –

+1

Mimo to, rekwizyty dla wielu komend 'ALTER COLUMN' rozdzielonych przecinkami! - Nigdy wcześniej nie zauważyłem tego w składni. –