【问题标题】:PostgreSQL - set a default cell value according to another cell valuePostgreSQL - 根据另一个单元格值设置默认单元格值
【发布时间】:2013-05-20 05:14:32
【问题描述】:

如果我有一列说任何给定值的column a,并且我希望另一列column b 根据column a 的值有一个default value

换句话说:
如果column a = 'peter' 那么column b default value = 'doctor'

【问题讨论】:

    标签: postgresql database-design triggers default-value postgresql-9.2


    【解决方案1】:

    不可能使用简单的DEFAULT 值,如the manual clearly states

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

    您可以改用trigger

    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 起可用):这样触发器函数仅在它真正有用时才被执行。 (假设如果a IS NULL,我们可以让b IS NULL滑动。)

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

    【讨论】:

      【解决方案2】:

      在 PostgreSQL 12 或更高版本中,我们可以使用生成的列
      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.
      

      【讨论】:

        猜你喜欢
        • 2019-05-12
        • 1970-01-01
        • 2012-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-15
        相关资源
        最近更新 更多