问题很简单。如何添加列x到表y,但只有当x列不存在?我发现唯一的解决方案在这里如何检查列是否存在。

SELECT column_name 
FROM information_schema.columns 
WHERE table_name='x' and column_name='y';

当前回答

你可以这样做。

ALTER TABLE tableName drop column if exists columnName; 
ALTER TABLE tableName ADD COLUMN columnName character varying(8);

因此,如果该列已经存在,它将删除该列。然后将列添加到特定的表中。

其他回答

对于那些使用Postgre 9.5+的人(我相信你们大多数人都在使用),有一个非常简单和干净的解决方案

ALTER TABLE if exists <tablename> add if not exists <columnname> <columntype>

你可以这样做。

ALTER TABLE tableName drop column if exists columnName; 
ALTER TABLE tableName ADD COLUMN columnName character varying(8);

因此,如果该列已经存在,它将删除该列。然后将列添加到特定的表中。

可以添加到迁移脚本调用函数,并在完成时删除。

create or replace function patch_column() returns void as
$$
begin
    if exists (
        select * from information_schema.columns
            where table_name='my_table'
            and column_name='missing_col'
     )
    then
        raise notice 'missing_col already exists';
    else
        alter table my_table
            add column missing_col varchar;
    end if;
end;
$$ language plpgsql;

select patch_column();

drop function if exists patch_column();

下面是使用“DO”语句的简短版本:

DO $$ 
    BEGIN
        BEGIN
            ALTER TABLE <table_name> ADD COLUMN <column_name> <column_type>;
        EXCEPTION
            WHEN duplicate_column THEN RAISE NOTICE 'column <column_name> already exists in <table_name>.';
        END;
    END;
$$

您不能将这些作为参数传递,您需要在客户端对字符串进行变量替换,但这是一个自包含查询,仅在列已经存在时发出消息,如果不存在则添加,并且在其他错误(如无效数据类型)时将继续失败。

如果这些是来自外部来源的随机字符串,我不建议使用任何这些方法。无论您使用什么方法(作为查询执行的客户端或服务器端动态字符串),它都会导致灾难,因为它使您容易受到SQL注入攻击。

在Postgres 9.6中,如果这个选项不存在,可以使用它来实现

ALTER TABLE table_name ADD COLUMN IF NOT EXISTS column_name INTEGER;