47

If i have a column say column a of any given values, and i want another column column b to have a default value according to the value of column a

In another words:
if column a = 'peter' then column b default value = 'doctor'.

4

2 回答 2

68

使用简单的值是不可能的,因为手册明确指出DEFAULT

该值是任何无变量的表达式(不允许对当前表中的其他列进行子查询和交叉引用)。

您可以改用触发器

CREATE OR REPLACE FUNCTION trg_foo_b_default()
  RETURNS trigger
  LANGUAGE plpgsql AS
$func$
BEGIN
   -- For just a few constant options, CASE does the job:
   NEW.b := CASE NEW.a
               WHEN 'peter'  THEN 'doctor'
               WHEN 'weirdo' THEN 'shrink'
               WHEN 'django' THEN 'undertaker'
               ELSE NULL
            END;

   /*
   -- For more, or dynamic options, consider a lookup table:
   SELECT INTO NEW.b  t.b
   FROM   def_tbl t
   WHERE  t.a = NEW.a;
   */

   RETURN NEW;
END
$func$;


CREATE TRIGGER b_default
BEFORE INSERT ON foo
FOR EACH ROW
WHEN (NEW.b IS NULL AND NEW.a IS NOT NULL)
EXECUTE PROCEDURE trg_foo_b_default();

为了更有效地使用WHEN触发器定义中的子句(自 Postgres 9.0 起可用):这样触发器函数仅在它实际有用时才执行。(假设我们可以让b IS NULL滑动 if a IS NULL。)

以与值相似但略有不同的方式工作DEFAULT
使用默认值,您可以显式插入NULL以推翻默认值。这是不可能的,NULLinb被替换为从a.

于 2013-05-25T23:48:22.980 回答
8

在 PostgreSQL 12 或更高版本中,我们可以使用Generated Columns
https://www.postgresql.org/docs/12/ddl-generated-columns.html 示例:

create temp table foo (a text ,
      b text GENERATED ALWAYS AS (
      case when a = 'telegram' then 'im'
            WHEN a = 'proton' THEN 'email'
            WHEN  a = 'infinity' THEN 'idea'
            else 'bad idea'
            end
      ) stored);

--测试时间。

insert into foo(a) values ('infinity'); 
insert into foo(a) values ('infinity1');

返回;

   a     |    b
-----------+----------
 infinity1 | bad idea
 infinity  | idea

当您尝试insert into foo(b) values ('infinity1')产生错误时。

--ERROR:  cannot insert into column "b" DETAIL:  Column "b" is a generated column.
于 2021-10-14T11:30:12.987 回答