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

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

当前回答

Postgres 9.6新增ALTER TABLE tbl ADD COLUMN IF NOT EXISTS column_name。 所以这已经过时了。您可以在较旧的版本或变体中使用它来检查列名以外的其他内容。


CREATE OR REPLACE function f_add_col(_tbl regclass, _col  text, _type regtype)
  RETURNS bool
  LANGUAGE plpgsql AS
$func$
BEGIN
   IF EXISTS (SELECT FROM pg_attribute
              WHERE  attrelid = _tbl
              AND    attname  = _col
              AND    NOT attisdropped) THEN
      RETURN false;
   ELSE
      EXECUTE format('ALTER TABLE %s ADD COLUMN %I %s', _tbl, _col, _type);
      RETURN true;
   END IF;
END
$func$;

电话:

SELECT f_add_col('public.kat', 'pfad1', 'int');

成功返回true,否则返回false(列已经存在)。 对于无效的表名或类型名引发异常。

为什么是另一个版本?

This could be done with a DO statement, but DO statements cannot return anything. And if it's for repeated use, I would create a function. I use the object identifier types regclass and regtype for _tbl and _type which a) prevents SQL injection and b) checks validity of both immediately (cheapest possible way). The column name _col has still to be sanitized for EXECUTE with quote_ident(). See: Table name as a PostgreSQL function parameter format() requires Postgres 9.1+. For older versions concatenate manually: EXECUTE 'ALTER TABLE ' || _tbl || ' ADD COLUMN ' || quote_ident(_col) || ' ' || _type; You can schema-qualify your table name, but you don't have to. You can double-quote the identifiers in the function call to preserve camel-case and reserved words (but you shouldn't use any of this anyway). I query pg_catalog instead of the information_schema. Detailed explanation: How to check if a table exists in a given schema Blocks containing an EXCEPTION clause are substantially slower. This is simpler and faster. The manual:

提示 包含EXCEPTION子句的块要多得多 进出的成本比一个没有的街区要高。 因此,如果没有必要,不要使用EXCEPTION。

其他回答

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

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

下面的函数将检查列是否存在,如果返回适当的消息,否则它将把列添加到表中。

create or replace function addcol(schemaname varchar, tablename varchar, colname varchar, coltype varchar)
returns varchar 
language 'plpgsql'
as 
$$
declare 
    col_name varchar ;
begin 
      execute 'select column_name from information_schema.columns  where  table_schema = ' ||
      quote_literal(schemaname)||' and table_name='|| quote_literal(tablename) || '   and    column_name= '|| quote_literal(colname)    
      into   col_name ;   

      raise info  ' the val : % ', col_name;
      if(col_name is null ) then 
          col_name := colname;
          execute 'alter table ' ||schemaname|| '.'|| tablename || ' add column '|| colname || '  ' || coltype; 
      else
           col_name := colname ||' Already exist';
      end if;
return col_name;
end;
$$

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

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();

你可以这样做。

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

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

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

ALTER TABLE table_name ADD COLUMN IF NOT EXISTS column_name INTEGER;