【问题标题】:Is there a efficient way to delete every view/function/table/sp from a database?有没有一种有效的方法可以从数据库中删除每个视图/函数/表/sp?
【发布时间】:2011-08-26 06:34:55
【问题描述】:

在 DB2 联合数据库中(基于远程服务器和昵称),我需要清理模型并从另一个数据库重新创建它。我需要删除除那些服务器和昵称之外的所有数据库对象。

我知道如何从 SYSCAT 模式中检索对象列表。现在我需要在每个上运行 DROP 语句。显然,依赖关系会阻碍。

蛮力方法是循环运行 DROP,直到全部成功,但根据顺序(幸运与否),可能需要很长时间。

您是否知道一种有效地对 DROP 语句进行排序以使删除的总时间尽可能短的方法?

并不期望完美的解决方案。一个相当聪明的解决方案就足够了。

谢谢

【问题讨论】:

    标签: db2-luw


    【解决方案1】:

    您可能希望查看每个表的引用(根据http://www.ibm.com/developerworks/data/library/techarticle/dm-0401melnyk/,您可以使用syscat.references)并自己构建依赖关系树(应该可以使用临时表,如果您受限于仅限 sql)。然后你可能会从那棵树的底部掉下来。

    因此,基本上,我对您的问题的回答是,为了快速完成,只需在删除之前根据它们之间的引用对表进行排序。由于不应该有任何依赖循环,因此您应该始终能够选择一个未引用的表。放下并重复。

    如果您想先删除数据,您可能还希望看到这个(类似的?)问题:DB2 cascade delete command?

    如果我在某些时候错了,请纠正。这个答案基于我对其他数据库的经验,因此它可能并不完全适合 DB2。虽然它应该工作;)

    【讨论】:

    • 谢谢,但问题是我不仅要删除表,还要删除视图、函数和过程
    • 那么我将首先删除视图,然后是过程,然后是表。不过,我不知道如何计算视图的引用(互联网上说SYSCAT.TABDEP - publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/…)或过程(syscat.routines 应该列出过程,sourceschema 应该指向它所属的表?)。如果在 DB2 中,过程在触发时被解析,您应该能够一一删除所有函数,即使它们相互引用。
    • 与此同时,我想出了一个(几乎)可行的解决方案。公平起见,因为您提供了有价值的信息,请享受赏金。谢谢;)
    • 谢谢!即使不直接帮助您,也许其他人会从我的帖子中受益;)
    【解决方案2】:

    此查询能够根据语句所依赖的元素总数对语句进行排序。生成的顺序几乎没有故障,“蛮力”方法的第二遍仅包含少数对象(在数千个要删除的对象中)。

    问题,很慢……

    编辑:查询中有一个拼写错误,使其返回或多或少正确的数据,但速度非常慢。

    WITH FIRST_LEVEL_DEPENDENCIES (BSCHEMA, BNAME, DTYPE, DSCHEMA, DNAME) AS
    (
      SELECT T1.TABSCHEMA AS BSCHEMA, T1.TABNAME AS BNAME, T1.BTYPE, T1.BSCHEMA, T1.BNAME
        FROM SYSCAT.TABDEP T1
       WHERE T1.TABSCHEMA NOT LIKE 'SYS%'
         AND T1.BTYPE <> 'N'
       UNION ALL
      SELECT T1.ROUTINESCHEMA AS BSCHEMA, T1.SPECIFICNAME AS BNAME, T1.BTYPE, T1.BSCHEMA, T1.BNAME
        FROM SYSCAT.ROUTINEDEP T1
       WHERE T1.ROUTINESCHEMA NOT LIKE 'SYS%'
         AND T1.BTYPE <> 'N'
       UNION ALL
      SELECT T1.TABSCHEMA AS BSCHEMA, T1.TABNAME AS BNAME, 'T', T1.REFTABSCHEMA, T1.REFTABNAME
        FROM SYSCAT.REFERENCES T1
       WHERE T1.TABSCHEMA NOT LIKE 'SYS%'
    ),
    RECURSIVE_DEPENDENCIES (LEVEL, BSCHEMA, BNAME, DTYPE, DSCHEMA, DNAME) AS
    (
       SELECT 1, U.BSCHEMA, U.BNAME, U.DTYPE, U.DSCHEMA, U.DNAME
         FROM FIRST_LEVEL_DEPENDENCIES AS U
        UNION ALL
       SELECT LEVEL + 1, REC.BSCHEMA, REC.BNAME, U.DTYPE, U.DSCHEMA, U.DNAME
         FROM RECURSIVE_DEPENDENCIES REC,
              FIRST_LEVEL_DEPENDENCIES U
        WHERE LEVEL < 6
          AND U.BSCHEMA = REC.DSCHEMA
          AND U.BNAME = REC.DNAME
    )
    SELECT BSCHEMA, BNAME, COUNT(*)
      FROM RECURSIVE_DEPENDENCIES
     GROUP BY BSCHEMA, BNAME
     ORDER BY COUNT(*)
    

    【讨论】:

      【解决方案3】:

      我没有针对 DB2 的直接解决方案,但我可以建议:

      A) 在 Microsoft SQL Server 2008 中,已经解决了删除(而不是 DROP)尊重外键顺序的表的问题,在此链接:

      Generate Delete Statement From Foreign Key Relationships in SQL 2008?

      B) 在 Oracle PL/SQL 中,已经解决了关于外键顺序的 DELETE(而不是 DROP)问题,在此链接:

      How to generate DELETE statements in PL/SQL, based on the tables FK relations?

      我认为您可以安排这两个脚本之一,以获得 DB2 的解决方案。

      你同意还是不同意?

      编辑 1:在此链接:

      http://bytes.com/topic/db2/answers/183189-how-delete-tables-completely

      我可以阅读:

      罗伯特, 为什么不干脆

      LOAD FROM /dev/null of del replace into tablename NONRECOVERABLE
      

      - 这会很快截断表格,不确定是否 它默认回收空间更新统计信息? 这有一个额外的好处,你不必 以正确的 RI 顺序执行删除。 (尽管之后你必须做一个 SET INTEGRITY ) 好的

      编辑 2:请参阅以下内容:

      Dropping a schema and all of its contents in DB2 8.x

      【讨论】:

      猜你喜欢
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 2020-11-04
      相关资源
      最近更新 更多