【问题标题】:Truncate Table with Referential Constraint使用参照约束截断表
【发布时间】:2020-12-12 19:39:21
【问题描述】:

我有表“Item”和“Category”,其中“Item”包含一个引用“Category”的外键约束(即每个项目在其类别列中都有一个类别元素的名称)。此约束称为“CONSTRAINT_74E”。

当用户更改数据时,我需要覆盖整个数据库。为此,我使用 TRUNCATE 命令。我试图禁用约束以截断 CATEGORY:

command = "truncate table ITEM;";
s.execute(command); //throws no exception

command = "alter table ITEM disable constraint CONSTRAINT_74E;\n" +
                "truncate table CATEGORY;\n" +
                "alter table ITEM enable constraint CONSTRAINT_74E;";
s.execute(command);

这会产生以下异常:

org.h2.jdbc.JdbcSQLSyntaxErrorException: SQL 语句中的语法错误 “更改表项禁用 [*] 约束 CONSTRAINT_74E;截断 表类别;更改表项启用约束 CONSTRAINT_74E;"; 预期 "., ADD, SET, RENAME, DROP, ALTER";

SQL 语句:alter table ITEM 禁用约束 CONSTRAINT_74E; 截断表类别; alter table ITEM 启用约束 约束_74E; [42001-200]

我究竟需要做什么才能完成这项工作?我看不出我需要如何添加 SET/RENAME/etc。禁用后。

【问题讨论】:

  • 你为什么不直接使用delete from item;?或者实际上delete from category; delete from item;
  • 不会重置 id 列,对吧?这最终会成为大型数据库的问题吗?
  • 不,不会。但是我发现如果用户更改某些内容,您总是删除“整个数据库”(为什么不只是有问题的表?),这非常令人困惑。为什么不能简单地更新数据?
  • 数据库仅包含 4 个表,并且在数据库成为项目的要求时,仅实现覆盖而不是使用 java 观察更改要简单得多。

标签: java sql h2


【解决方案1】:

当然,您不能删除用作外键的数据,因为这会破坏参照完整性。您可以尝试删除外键,但如果键不同,再次添加它会中断 - 如果它们不同,您为什么首先截断?

根据您的要求,您有以下几种选择:

  • 不要截断,而是使用其他一些更新机制(我更喜欢这样,但我不知道您对截断的要求)
  • 完全移除外键约束并处理缺失/错误键
  • 在截断之前删除外键(即值),如果可能,在添加新数据后尝试重新插入它们

更新:因为您只要求语法(至少目前如此),请查看H2 commands documentation

在那里你会看到禁用外键检查,也就是引用完整性,可以使用这个命令来完成:

ALTER TABLE ITEM SET REFERENTIAL_INTEGRITY FALSE

似乎不支持禁用其他约束,因此您可能不得不删除并再次添加它们。

顺便说一句:

我不明白我需要如何添加 SET/RENAME/等。禁用后。

请注意,...expected "., ADD, SET, RENAME, DROP, ALTER"; 并不意味着语句解析器需要在 DISABLE 之后提到的命令,而是而不是重命名,即在这个位置不支持 DISABLE(如果有的话)。

【讨论】:

  • 但是我已经删除了包含引用外键的项目。同样据我了解,禁用命令旨在禁用该确切约束。
  • @Magoni 我明白了,您应该将其添加到您的帖子中,以便我们获得该信息。
  • @Magoni 啊,是的,我看到你也截断了 ITEMS。在那种情况下,为什么需要禁用约束?截断 CATEGORY 应该仍然有效,因为不会违反约束(没有外键就没有违反)。
  • 我真的不知道,但是当我不使用它时,我得到“org.h2.jdbc.JdbcSQLSyntaxErrorException: Cannot truncate "PUBLIC.CATEGORY"; SQL statement: TRUNCATE TABLE CATEGORY" 然后我读到这可能是因为约束仍然有效。
  • @Magoni 好吧,当您尝试直接在 SQL 客户端中执行此操作时会发生什么?
猜你喜欢
  • 2019-11-04
  • 2011-07-24
  • 2020-09-07
  • 2016-07-28
  • 2014-04-06
  • 2019-11-30
  • 1970-01-01
相关资源
最近更新 更多