仅当主键存在时才更新外键

Updating a foreign key only when primary key exists

我有以下一段代码。我想更新外键 如果对应的主键存在。

请查看查询编号: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;

查询 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;

问题 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;  

是否可以通过 join 以有效的方式执行上述查询。我不希望两次调用本质上相同的子查询。我目前正在这样做。一次用于 EXISTS 语句,一次用于主查询。

您可以使用 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。下次您从 id1id3 列后面的序列创建记录时,您将遇到主键冲突。 bigserial 类型的全部目的是让 PostgreSQL 管理主键值。