在INSERT语句中将一列的默认值设置为另一列

时间:2012-03-01 20:55:03

标签: database postgresql

我有一个表,称之为t1,有三个整数列c1,c2,c3。 c1的默认值为:

not null default nextval

对于我目前正在进行的INSERT语句,我希望c2具有与将分配给c1相同的值。对于我的大多数插入都不是这种情况,因此将c2定义为具有默认值或在更新时具有触发器是没有意义的。目前我正在做两个陈述:

INSERT INTO t1 (c3) VALUES (val3);
UPDATE t1 SET c2 = c1 WHERE //Get correct row

3 个答案:

答案 0 :(得分:7)

无保证,其中将处理集合的订单元素。还有不需要进行两次函数调用。使用子选择或CTE

INSERT INTO t (c1, c2, c3)
SELECT x.s, x.s, val3
FROM  (SELECT nextval('c1_seq') AS s) x;

或使用CTE:

WITH   x(s) AS (SELECT nextval('c1_seq'))
INSERT INTO t (c1, c2, c3)
SELECT x.s, x.s, val3
FROM   x;

答案 1 :(得分:2)

在您的情况下,您需要将 c2 的默认值设置为序列的当前值,与 c1 相关联,即:

ALTER TABLE
  t1
ALTER COLUMN
  c2
SET DEFAULT
  CURRVAL(PG_GET_SERIAL_SEQUENCE('t1', 'c1'));

当然,如果您为 c1 指定了一些显式值,那么这将不起作用。如果存在这种情况,那么您应该进行BEFORE触发,以确保 c2 始终 c1 相同插入

CREATE FUNCTION sync_c2() RETURNS trigger AS $$
BEGIN
  IF NEW.c2 IS NULL THEN
    NEW.c2 := NEW.c1;
  END IF;

  RETURN NEW;
END;
$$ LANGUAGE plpgsql;


CREATE TRIGGER
  sync_c2
BEFORE INSERT ON
  t1
FOR EACH ROW EXECUTE PROCEDURE
  sync_c2();

答案 2 :(得分:1)

c1的默认值仅在您没有为其提供显式值时使用,当然,如果您在VALUES中明确要求使用default,则会使用默认值。您也可以使用VALUES中的nextval and currval自由访问序列; nextval函数执行此操作:

  

提前序列并返回新值。

currval

  

最近使用nextval获取指定序列

的返回值

因此,您可以执行此操作以获取c1的下一个序列值,并为c2获取相同的值:

insert into t1 (c1, c2, c3) values (nextval('c1_seq'), currval('c1_seq'), val3)

其中c1_seq是您用于为c1提供默认值的序列的名称。