如何在 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 | |
在 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 | |