【问题标题】:Cannot drop table users because other objects depend on it无法删除表用户,因为其他对象依赖于它
【发布时间】:2016-05-22 04:37:14
【问题描述】:

我想在我的数据库中删除我的表。 但是,例如,当我使用时, DROP TABLE if exists users; 我收到这条消息:

cannot drop table users because other objects depend on it

我发现解决方案是删除所有表。但是,无论如何,如何在不删除全部数据的情况下解决这个问题?

【问题讨论】:

  • 基于外键约束,您需要根据条件删除
  • 多考虑一下你在做什么。首先证明有必要删除表。
  • Delete from Table2 t where t.Col1 in (Select 1 from table1 tt where tt.col1 = t.col1) 删除后现在删除要删除的表
  • @mohan111:删除引用表中的行根本没有帮助。需要删除外键。

标签: sql postgresql


【解决方案1】:

使用cascade 选项:

DROP TABLE if exists users cascade;

这将删除引用users 表或使用它的任何视图的任何外键。

它不会删除其他(或从中删除行)。

【讨论】:

  • 会在依赖于用户的其他表中删除行吗?
  • @PaulinTrognon:不,它只会删除引用该表和表本身的外键约束,不会删除或删除其他任何内容
  • 它还会删除所有引用您的表的视图。
  • 在我的情况下它实际上删除了两个表,所以请注意。我相信这是因为我通过继承第一个表创建了第二个表!
  • 没错,希望其他收到此错误cannot drop table users because other objects depend on it 的人在检查约束是什么之前不会犯同样的错误。只是想分享
【解决方案2】:

如果确实有必要删除该特定表并重新创建或不重新创建它,那么首先找到依赖于它的对象。

CREATE OR REPLACE VIEW admin.v_view_dependency AS 
SELECT DISTINCT srcobj.oid AS src_oid
  , srcnsp.nspname AS src_schemaname
  , srcobj.relname AS src_objectname
  , tgtobj.oid AS dependent_viewoid
  , tgtnsp.nspname AS dependant_schemaname
  , tgtobj.relname AS dependant_objectname
FROM pg_class srcobj
  JOIN pg_depend srcdep ON srcobj.oid = srcdep.refobjid
  JOIN pg_depend tgtdep ON srcdep.objid = tgtdep.objid
  JOIN pg_class tgtobj ON tgtdep.refobjid = tgtobj.oid AND srcobj.oid <> tgtobj.oid
  LEFT JOIN pg_namespace srcnsp ON srcobj.relnamespace = srcnsp.oid
  LEFT JOIN pg_namespace tgtnsp ON tgtobj.relnamespace = tgtnsp.oid
WHERE tgtdep.deptype = 'i'::"char" AND tgtobj.relkind = 'v'::"char";

那么,

select top 99 * from admin.v_view_dependency where src_objectname like '%the_table_name_it_complaint_about%';

结果集将在“dependant_objectname”字段中显示依赖对象。

【讨论】:

    【解决方案3】:

    一般来说,要删除几个相互依赖的表,您从没有任何依赖关系的表开始(具有指向 其他表的外键的表),然后向后工作。例如,如果表 transactions 依赖于表 users,您将首先删除 transactions。简而言之:按照与创建表相反的顺序删除表。

    如果您设法创建具有循环依赖关系的表,您可以先删除阻止删除的外键约束。或者您可以使用修饰符CASCADE,它(正如@a_horse 在 cmets 中解释的那样)将删除任何涉及已删除表的外键约束。但请注意,并非所有 DBMS 都支持CASCADE:Postgres 支持,但 MySQL 不支持(关键字被接受但无效)。

    【讨论】:

    • 需要使用外键检查和修改每条记录” - 这是完全错误的。 cascade 选项检查引用表中的所有行 - 它只是删除外键。它不会删除任何数据。
    • 我是按照您的描述进行的:要“删除正在使用用户表的外键”,您需要修改包含外键的记录。但实际上the manual 建议删除整个子表,而不仅仅是记录或键:“自动删除依赖于表的对象(例如视图)。”你能澄清一下吗?
    • 这种情况下的依赖对象是外键约束不是表。 drop table ... cascade 不会删除其他表中的任何行,也不会删除除 DDL 语句中提到的表之外的任何其他表。证明见这里:sqlfiddle.com/#!15/8d258/1
    • 感谢您的澄清!已更正。
    • 如果您使用“级联”选项删除数据库用户,它将删除所有依赖对象。例如用户拥有的所有表(以及这些表中的所有数据)。因此,使用“级联”时可能会意外丢失所有数据和架构。
    猜你喜欢
    • 2017-04-14
    • 2018-09-01
    • 2020-12-27
    • 2023-03-08
    • 1970-01-01
    • 2013-06-06
    • 2018-12-17
    • 2021-05-27
    • 1970-01-01
    相关资源
    最近更新 更多