更新或删除违反外键约束

时间:2019-04-30 18:51:16

标签: sql postgresql

我有两个看起来像下面的表。

CREATE TABLE book (
    book_id BIGSERIAL PRIMARY KEY,
    book_special_id character(10) NOT NULL DEFAULT random_string(10) UNIQUE,
    author_id bigint REFERENCES author(author_id) ON DELETE RESTRICT,
    category_id bigint REFERENCES category(category_id) ON DELETE RESTRICT,
    title text NOT NULL,
    subtitle text,
    book_text text
);

CREATE TABLE booksubcategory (
    booksubcategory_id BIGSERIAL PRIMARY KEY,
    book_id BIGSERIAL REFERENCES book(book_id) ON DELETE CASCADE,
    subcategory_id BIGSERIAL REFERENCES subcategory(subcategory_id) ON DELETE RESTRICT,
    CONSTRAINT booksubcategory_book_id_subcategory_id_key UNIQUE (book_id, subcategory_id)
);

在此示例中,book_id列是book表中的主键,而在booksubcategory表中是引用的外键。当我尝试运行以下sql时,收到错误消息:

ERROR: update or delete on table "book" violates foreign key constraint "booksubcategory_book_id_fkey" on table "booksubcategory"
Detail: Key (book_id)=(888392) is still referenced from table "booksubcategory"

这是SQL的样子。

INSERT INTO book (book_special_id, author_id, category_id, title, subtitle, book_text) 
VALUES ("D4jOko2IP0",34, 4, "Book Example", "Book Subtitle", "Some lengthy text") 
ON CONFLICT (book_special_id) 
DO UPDATE SET author_id=EXCLUDED.author_id, book_id=EXCLUDED.book_id,  category_id=EXCLUDED.category_id, title=EXCLUDED.title, subtitle=EXCLUDED.subtitle, book_text=EXCLUDED.book_text;

在这种情况下,由于书表中已经存在book_special_key,因此sql应该更新列。

我熟悉外键约束的更新和删除由于完整性原因而失败的原因,但就我而言,我不是直接更新book_id,而只是直接更新book表中的列。另外,我在子表的外键上设置了ON DELETE CASCADE。有人可以告诉我为什么我遇到这个问题吗?

1 个答案:

答案 0 :(得分:1)

插入的行与唯一键special_book_id冲突,然后冲突规则将尝试更新重复的行。

但是由于冲突而尚未插入且为autogen的NEW行的值book_id是什么?好吧,可以是null或新序列号。

因此,无论哪种情况,您都将book_id更新为null或新的序列号,但由于旧的book_id值(正在消失)具有引用,因此失败。

将更新删除到book_id列,它应该可以工作。