我有以下代码。我想更新一个外键 如果存在相应的主键。
请查看第2号查询和第3号查询。
DROP SCHEMA IF EXISTS s CASCADE;
CREATE SCHEMA s;
CREATE TABLE s.t1 (
"id1" BigSerial,
"id2" BigInt,
CONSTRAINT "pk1" PRIMARY KEY (id1)
)
WITH(OIDS=FALSE);
CREATE TABLE s.t2 (
"id3" BigSerial,
"id4" Varchar UNIQUE NOT NULL,
CONSTRAINT "pk2" PRIMARY KEY (id3)
)
WITH(OIDS=FALSE);
ALTER TABLE s.t1 ADD CONSTRAINT "fk" FOREIGN KEY (id2) REFERENCES s.t2 (id3) ON DELETE NO ACTION ON UPDATE NO ACTION;
INSERT INTO s.t2 (id3, id4) VALUES (1, 'hello');
INSERT INTO s.t2 (id3, id4) VALUES (21, 'hello2');
INSERT INTO s.t2 (id3, id4) VALUES (31, 'hello3');
INSERT INTO s.t1 (id1, id2) VALUES (2, 21);
INSERT INTO s.t1 (id1) VALUES (3);
SELECT id1, id2 FROM s.t1;
UPDATE s.t1
SET id2 = (SELECT id3 FROM s.t2 WHERE s.t2.id4 = 'hello') WHERE s.t1.id1 = 2;
SELECT id1, id2 FROM s.t1;
QUERY 2
UPDATE s.t1
SET id2 = (SELECT id3 FROM s.t2 WHERE s.t2.id4 = 'xyz') WHERE s.t1.id1 = 2
AND EXISTS (SELECT 1 FROM s.t2 WHERE s.t2.id4 = 'xyz');
SELECT id1, id2 FROM s.t1;
QUERY 3
UPDATE s.t1
SET id2 = (SELECT id3 FROM s.t2 WHERE s.t2.id4 = 'hello3') WHERE s.t1.id1 = 2
AND EXISTS (SELECT 1 FROM s.t2 WHERE s.t2.id4 = 'hello3');
SELECT id1, id2 FROM s.t1;
DROP SCHEMA s CASCADE;
是否可以通过加入以有效的方式执行上述查询。我不希望两次调用基本相同的子查询。我目前正在这样做。一次用于EXISTS语句,一次用于主查询。
答案 0 :(得分:0)
您可以使用CTE评估子查询一次,然后多次使用它:
WITH find_rec AS
(SELECT id3 FROM s.t2 WHERE id4 = 'hello3')
UPDATE s.t1
SET id2 = find_rec.id3
WHERE id1 = 2
AND EXISTS (SELECT 1 FROM find_rec);
更一般地说,您应该永远不要手动为bigserial
列分配值。下次从id1
或id3
列后面的序列创建记录时,您将收到主键违规。 bigserial
类型的全部目的是让PostgreSQL管理主键值。