在SQL Insert上,在事务期间,如何将此新行中另一个字段的值复制到另一个字段?

时间:2016-01-19 02:30:59

标签: sql postgresql

我有一张表格如下:

FORMS
----
form_id bigint NOT NULL DEFAULT id_generator(),
...
...
form_pretty_url character varying NOT NULL DEFAULT 'form-'::*GET_FORM_ID*

从这里复制id_generator函数: http://rob.conery.io/2014/05/29/a-better-id-generator-for-postgresql/

CREATE OR REPLACE FUNCTION id_generator(OUT result bigint) AS $$
DECLARE
    our_epoch bigint := 1314220021721;
    seq_id bigint;
    now_millis bigint;
    shard_id int := 5;
BEGIN
    SELECT nextval('insta5.table_id_seq') % 1024 INTO seq_id;
    SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
    result := (now_millis - our_epoch) << 23;
    result := result | (shard_id << 10);
    result := result | (seq_id);
END;
$$ LANGUAGE PLPGSQL;

调用last_value或currval(),lastval()或任何其他可用函数不会返回我想要的内容。

正在使用的数据库是PostgreSQL。

1 个答案:

答案 0 :(得分:1)

列的默认值无法引用其他列。有一个特定的错误消息:

=> create table tst(i int, j int default i);
ERROR:  cannot use column references in default expression

您可以使用BEFORE INSERT触发器来获得所需的结果。 由于该列存在NOT NULL约束,因此仍需要非空的默认值,因为约束已经过检查,并且在运行触发器之前必须有效。

定义变更:

 form_pretty_url character varying NOT NULL DEFAULT '';

触发示例:

CREATE FUNCTION trigfunc() RETURNS TRIGGER as $$
BEGIN
  IF NEW.form_pretty_url = '' THEN
     NEW.form_pretty_url := 'form-' || NEW.form_id::text; 
  END IF;
  RETURN NEW;
END $$ language plpgsql;


CREATE TRIGGER trigname BEFORE INSERT  ON tablename
  FOR EACH ROW EXECUTE PROCEDURE trigfunc();