奇怪的规则适用于PostgreSql 9.5 / 9.6上的插入

时间:2016-12-09 15:14:24

标签: sql postgresql

示例:

CREATE TABLE public.test
(
id bigserial NOT NULL,
name text
);


ALTER TABLE public.test
ADD CONSTRAINT test_constraint_pkey PRIMARY KEY(id);


CREATE TABLE public.v_test
(
id bigserial NOT NULL,
v_id bigint,
v_name text
);


ALTER TABLE public.v_test
ADD CONSTRAINT v_test_constraint_pkey PRIMARY KEY(id);


CREATE OR REPLACE RULE insert AS
ON INSERT TO test DO INSERT INTO v_test (v_id, v_name)
VALUES (new.id, new.name);

然后执行

insert into test(name)
values 
('1'),
('2'),
('3')
test.id<>中的

值v_test.v_id

从PPA http://apt.postgresql.org/pub/repos/apt

安装postgresql 9.5 / 9.6进行测试

OS ubuntu-sever 14.04 / 16.04

2 个答案:

答案 0 :(得分:1)

实际上并非如此。这是Postgresql支持中所说的内容

  

这是预期的行为,因为规则就像宏一样工作   你有一个volatile参数(也就是nextval()调用   串行列的默认值被传递给它,从而被执行   两次。 IOW,你写的相当于

     

插入测试(id,name)值(nextval(' test_id_seq'),' 1'),   (nextval(' test_id_seq'),' 2'),(nextval(' test_id_seq'),' 3');

     

然后执行,然后规则也会执行此操作:

     

插入v_test(v_id,v_name)值(nextval(' test_id_seq'),   ' 1'),(nextval(' test_id_seq'),' 2'),(nextval(' test_id_seq'),' 3&#39);

     

使用触发器可以更加可靠地完成您的想象。

答案 1 :(得分:0)

是的,我明白了你的意思 - 我测试了它,我总是从序列进入v_test.v_id下一个ID值。如果您尝试仅将一个新记录插入test表中,则会更加明显。不幸的是,规则无法引用old.id值。