Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL“可延迟删除”在删除时仍会遇到约束_Sql_Postgresql_Transactions_Cascade - Fatal编程技术网

PostgreSQL“可延迟删除”在删除时仍会遇到约束

PostgreSQL“可延迟删除”在删除时仍会遇到约束,sql,postgresql,transactions,cascade,Sql,Postgresql,Transactions,Cascade,我想通过一组可延迟约束从两个相互依赖的表中删除行。为了简化这篇文章,我模拟了一个简单的DB模式 我希望在SQL transaction/DB补丁中删除某些表中的条目“delete_from_me”。问题是,我想在松开链接之前,根据第二个表“constraining_table”中的选择删除 以下是两个表的说明: tab-quarantine=> \d delete_from_me Table "public.delete_from_me" Column |

我想通过一组可延迟约束从两个相互依赖的表中删除行。为了简化这篇文章,我模拟了一个简单的DB模式

我希望在SQL transaction/DB补丁中删除某些表中的条目“delete_from_me”。问题是,我想在松开链接之前,根据第二个表“constraining_table”中的选择删除

以下是两个表的说明:

tab-quarantine=> \d delete_from_me
       Table "public.delete_from_me"
  Column   |       Type        | Modifiers 
-----------+-------------------+-----------
 id        | character varying | not null
 extension | character varying | not null
Indexes:
    "delete_from_me_pkey" PRIMARY KEY, btree (id)

tab-quarantine=> \d constraining_table 
   Table "public.constraining_table"
 Column |       Type        | Modifiers 
--------+-------------------+-----------
 image  | character varying | not null
 type   | character varying | not null
Foreign-key constraints:
    "constraining_table_image_fkey" FOREIGN KEY (image) REFERENCES delete_from_me(id)
         ON UPDATE CASCADE
         ON DELETE RESTRICT DEFERRABLE
以下是我刚才在这里列举的一些示例数据:

tab-quarantine=> SELECT * FROM delete_from_me;
     id     | extension 
------------+-----------
 12345abcde | png
(1 row)

tab-quarantine=> SELECT * FROM constraining_table;
   image    |   type   
------------+----------
 12345abcde | select_me
(1 row)
下面是我的交易:

BEGIN;
\set ON_ERROR_STOP 1
SET CONSTRAINTS ALL DEFERRED;
DELETE FROM delete_from_me WHERE id IN (
    SELECT image FROM constraining_table WHERE type = 'select_me'
);
DELETE FROM constraining_table WHERE type = 'select_me';
COMMIT;
此事务失败。当我单步执行并手动执行此操作时,会显示以下错误消息:

ERROR:  update or delete on table "delete_from_me" violates foreign key constraint "constraining_table_image_fkey" on table "constraining_table"
DETAIL:  Key (id)=(12345abcde) is still referenced from table "constraining_table".
这似乎是一个很好的临时表候选项,但是我想知道为什么我不能按此顺序删除,因为约束在事务结束之前不应该有效?

使用ON delete NO ACTION deliverable而不是ON delete RESTRICT deliverable。使用“限制”而不是“无操作”会强制约束不可延迟,无论是否应用“可延迟”修改器

这一点在以下文件中有详细说明:

即使约束声明为可延迟,也不能延迟除无操作检查之外的引用操作

显然,上述警告包括限制

本句后面紧接着是“不采取行动”和“限制”的定义:

不采取行动

生成一个错误,指示删除或更新将创建外键约束冲突。如果约束被延迟,如果仍然存在任何引用行,则在约束检查时将产生此错误。这是默认操作

限制

生成一个错误,指示删除或更新将创建外键约束冲突。这与无操作相同,只是检查不可延迟

正如您所看到的,除了没有可延迟的操作外,任何操作的行为都不会与限制相同。这就是我推荐它的原因——我想这正是你想要的