【问题标题】:Strange the rule works for an insertion on PostgreSql 9.5/9.6奇怪的规则适用于 PostgreSql 9.5/9.6 上的插入
【发布时间】:2016-12-09 15:14:24
【问题描述】:

示例:

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 上测试

操作系统 ubuntu-sever 14.04/16.04

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    其实并非如此。这就是 Postgresql 支持中所说的

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

    插入 test(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');

    使用触发器可以更可靠地完成您似乎想要的事情。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2017-05-17
        • 2017-11-22
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 2016-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多