当对 Postgres 中的外部表调用 TRUNCATE CASCADE 时,带有 ON DELETE SET NULL 的外键仍会被删除

Rya*_*ini 7 postgresql truncate

也许我在这里遗漏了一些东西:

CREATE TABLE public.example_table (
    id integer UNIQUE
);

CREATE TABLE public.foreign_table (
    id integer,
    example_table_id integer,
    CONSTRAINT fk_example_table_id
    FOREIGN KEY (example_table_id)
    REFERENCES public.example_table (id)
    ON DELETE SET NULL
);

INSERT INTO public.example_table (id) VALUES
    (1);

INSERT INTO public.foreign_table (id, example_table_id) VALUES
    (1, 1),
    (2, null);
Run Code Online (Sandbox Code Playgroud)

如果我运行TRUNCATE CASCADE,两个表都会被擦除,这不是我预期会发生的情况。

TRUNCATE example_table CASCADE;

SELECT COUNT(*) FROM public.foreign_table;

0
Run Code Online (Sandbox Code Playgroud)

我期望发生的情况会foreign_table改变为:

(1, null)
(2, null)
Run Code Online (Sandbox Code Playgroud)

我是否不明白 SET NULL 应该完成什么?

有没有办法使用 TRUNCATE CASCADE 而不将其从另一个表中删除?我在可以调用的地方使用 Laravel Model::truncate();,它会自动截断表并重置我的索引,我希望我可以调用它example_table并让它重置所有行foreign_tablenull而不是仅仅删除整个表。

感谢您的帮助。

Len*_*art 6

如果我正确理解文档:

https://www.postgresql.org/docs/current/sql-truncate.html

TRUNCATE CASCADE 会截断具有指向(引用)公共表的外键关系的每个表,无论为外键指定什么操作。

另请注意,外键上指定的操作是ON DELETEON UPDATE。没有定义ON TRUNCATE操作的选项。

例子:

create table parent 
( x int not null primary key);

create table child 
( y int not null primary key
, x int not null references parent(x) 
                 on delete restrict 
                 on update restrict
);

insert into parent (x) values (1),(2),(3);
insert into child (y,x) values (1,1),(3,2);

truncate parent cascade;

select * from child;

There are no results to be displayed.
Run Code Online (Sandbox Code Playgroud)

是否有什么特别的事情阻止您:

delete from parent;
Run Code Online (Sandbox Code Playgroud)

  • 我同意,这似乎是行为,但这不是我所期望的。我将使用“删除”来代替。 (2认同)