我认为这是旧查询的另一个转折点,我已经搜索了一个没有成功的解决方案。
我有一张表,比如两个值:
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),
...
那么,函数是唯一的方法吗?
答案 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
;