如何在 postgresql 9.3 上添加新列时模仿 "IF NOT EXISTS"?

How to mimic "IF NOT EXISTS" when adding a new column on postgresql 9.3?

在 postgresql 9.3 上,没有用于在 table 上添加新列的 IF NOT EXISTS 指令。所以我显然得到了一个语法错误,通过尝试使用它:

ALTER TABLE rooms ADD COLUMN IF NOT EXISTS color VARCHAR(6);


ERROR:  syntax error at or near "NOT"
LINE 1: ALTER TABLE rooms ADD COLUMN IF NOT EXISTS color VARCHAR(6);

由于我没有可能升级到更新的版本,执行此操作的替代方法是什么?

一种可能:

\d animals
                      Table "public.animals"
 Column |          Type          | Collation | Nullable | Default 
--------+------------------------+-----------+----------+---------
 id     | integer                |           | not null | 
 cond   | character varying(200) |           | not null | 
 animal | character varying(200) |           | not null | 
Indexes:
    "animals_pkey" PRIMARY KEY, btree (id)

DO
$$
BEGIN
    perform * from pg_attribute where attrelid = 'animals'::regclass and attname = 'cond';
    IF FOUND THEN
        RAISE NOTICE 'Column exists';
    ELSE 
        ALTER TABLE animals ADD COLUMN cond varchar;
    END IF;
END$$;
NOTICE:  Column exists
DO

DO
$$
BEGIN
    perform * from pg_attribute where attrelid = 'animals'::regclass and attname = 'new_col';
    IF FOUND THEN
        RAISE NOTICE 'Column exists';
    ELSE 
        ALTER TABLE animals ADD COLUMN new_col varchar;
    END IF;
END$$;
DO

\d animals
                      Table "public.animals"
 Column  |          Type          | Collation | Nullable | Default 
---------+------------------------+-----------+----------+---------
 id      | integer                |           | not null | 
 cond    | character varying(200) |           | not null | 
 animal  | character varying(200) |           | not null | 
 new_col | character varying      |           |          | 
Indexes:
    "animals_pkey" PRIMARY KEY, btree (id)

这是一个匿名函数(DO),但它可以成为一个常规函数,例如add_column(table_name varchar, column_name varchar)

更新

常规函数:

CREATE OR REPLACE FUNCTION public.add_column(table_name character varying, column_name character varying, col_type character varying)
 RETURNS void
 LANGUAGE plpgsql
AS $function$
BEGIN
    perform * from pg_attribute where attrelid = table_name::regclass and attname = quote_ident(column_name);
    IF FOUND THEN
        RAISE NOTICE 'Column exists';
    ELSE
        EXECUTE 'ALTER TABLE animals ADD COLUMN  '|| quote_ident(column_name) || ' ' ||col_type;
    END IF;
END;
$function$
;
select add_column('animals', 'int_col', 'integer');
 add_column 
------------
 
\d animals
                      Table "public.animals"
 Column  |          Type          | Collation | Nullable | Default 
---------+------------------------+-----------+----------+---------
 id      | integer                |           | not null | 
 cond    | character varying(200) |           | not null | 
 animal  | character varying(200) |           | not null | 
 new_col | character varying      |           |          | 
 int_col | integer                |           |