使用(插入...返回id)作为值 - Postgresql

时间:2014-09-08 15:14:59

标签: postgresql insert

认为这是旧查询的另一个转折点,我已经搜索了一个没有成功的解决方案。

我有一张表,比如两个值:

create table source (
a varchar(10) not null unique,
b varchar(10) not null
);

它有100000的价值。

我想用它们来初始化两个已知为空的链表(即这不是一个问题):

create table t1 (
id serial primary key,
x varchar(10) unique
);

create table t2 (
y varchar(10),
xp int not null references t1(id)
);

以下概念上是我想要的,但不允许:

insert into t2(y,xp) select b,(insert into t1(x) values (a) returning id) from source;

理想情况下,我想避免多次循环遍历源表。

最好的解决方案我发现有效的方法是定义一个函数插入到t1中,给出

insert into t2(y,xp) select b,t1_ins(a) from source;

有些令人惊讶的是,定义明显的视图和ON INSERT规则失败了:

create view t2plus (
/* from t2 */
y,
/* from t1 */
x
)
as select y, x
from t2, t1 where t1.id=t2.xp;

create rule t2p_insert as on insert
to t2plus do instead
( INSERT INTO t1(X) VALUES (NEW.x);
INSERT INTO t2(y,xp) VALUES (NEW.y,currval('t1_id_seq')) returning xp;
);

这给出了一个模糊但明确的错误:   WITH声明中的数据修改语句不支持多语句DO INSTEAD规则! (我的大源阵列实际上是一个CTE) 调用时如下:

with source as (.....),
nextTab as (insert into t2plus(y,x) select x,y from source where y is not null),
...

那么,函数是唯一的方法吗?

1 个答案:

答案 0 :(得分:0)

create table source (
        a varchar(10) not null,
        b varchar(10) not null
        );

create table t1 (
        id serial primary key,
        x varchar(10) unique
        );

create table t2 (
        y varchar(10),
        xp int not null references t1(id)
        );

INSERT INTO source(a,b) VALUES
          ( 'a1' ,'b1' ) , ( 'a1' ,'b2' )
        , ( 'a2' ,'b1' ) , ( 'a2' ,'b2' )
        ;

WITH ins AS (
        INSERT INTO t1 (x)
        SELECT DISTINCT s.a
        FROM source s
        WHERE NOT EXISTS (
                SELECT * FROM t1 nx
                WHERE nx.x = s.a
                )
        RETURNING t1.id, t1.x
        )
, sel AS (
        select t1.id, t1.x
        FROM t1
        WHERE EXISTS (
                SELECT *
                FROM source ex
                WHERE ex.a = t1.x
                )
        )
, two AS (
        SELECT ins.id, ins.x FROM ins
        UNION ALL
        SELECT sel.id, sel.x FROM sel
        )
INSERT INTO t2 (xp, y)
SELECT b.id, s.b
FROM source s
JOIN two b ON b.x = s.a
        ;

SELECT * FROM t1;
SELECT * FROM t2;

SELECT t1.id, t1.x
        , t2.y
FROM t1
JOIN t2 ON t2.xp = t1.id
        ;