有没有一种有效的方法可以从数据库中删除每个视图/函数/表/sp?

发布于 2024-11-07 07:15:37 字数 288 浏览 7 评论 0原文

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

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

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

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

预计不会有完美的解决方案。一个相当聪明的解决方案就足够了。

谢谢

In a DB2 federated database (based on remote servers and nicknames), I need to clean up the model and recreate it from another database. I need to delete every database object except those servers and nicknames.

I know how to retrieve the list of objects from the SYSCAT schema. Now I need to run the DROP statements on each. Obviously the dependencies will get in the way.

The brute force approach would be to run the DROPs in a loop until all have succeeded, but depending on the order (lucky or not), it could take a very long time.

Would you know a way to efficiently order the DROP statement so that the total time for the deletion is the shortest possible?

A perfect solution is not expected. A reasonably clever solution is good enough.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

瑾夏年华 2024-11-14 07:15:37

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

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

您可能还希望看到这个(类似?)问题:DB2cademic delete command?以防万一你想先删除数据。

如果我在某些地方错了,请纠正。这个答案是基于我使用其他数据库的经验,因此它可能不完全适合 DB2。虽然它应该有效;)

You might want to see the references of each table (which you can do with syscat.references according to http://www.ibm.com/developerworks/data/library/techarticle/dm-0401melnyk/) and built a tree of the dependencies yourself (should be doable e.g. with temporary tables, if you are restricted to sql only). Then you may drop from the bottom of that tree.

So, basically, my answer to your question would be that in order to do it quick, just order the tables based on the references they have between themselves before deleting. Since there should not be any dependency cycles, you should always be able to pick one table which is not referenced. Drop it and repeat.

You might also wish to see this (similar?) question: DB2 cascade delete command? in case you want to delete the data first.

If I am wrong at some point, please correct. This answer is based on my experiences with other databases, therefore it might not be fully suitable for DB2. Although it should work ;)

薄荷→糖丶微凉 2024-11-14 07:15:37

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

问题,它非常慢...

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

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(*)

This query is able to order the statements according to the total number of elements they depend on. The resulting order works almost without a glitch, the second pass of the "brute force" approach contains only a handful of objects (out of several thousands objects to delete).

Problem, it is very slow...

EDIT : There was a typo in the query that made it return more or less correct data but very very slowly.

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(*)
柏拉图鍀咏恒 2024-11-14 07:15:37

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

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

从 SQL 2008 中的外键关系生成删除语句?

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

如何根据表FK关系在PL/SQL中生成DELETE语句?

我认为您可以安排这两个脚本之一,以获得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:请参阅以下内容:

删除 DB2 8.x 中的模式及其所有内容

I have not a DIRECT solution for DB2, but I can suggest that:

A) In Microsoft SQL Server 2008, it has been solved the problem to DELETE (not DROP) the tables respecting foreign keys order, at this link:

Generate Delete Statement From Foreign Key Relationships in SQL 2008?

B) In Oracle PL/SQL, it has been solved the problem to to DELETE (not DROP) respecting foreign keys order, at this link:

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

I think you can arrange one of these two scripts, in order to obtain the solution for DB2.

Do you agree or not?

EDIT 1: At this link:

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

I can read:

Robert,
why not simply

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

- This truncates the table very quickly, not sure if
it reclaims space updates stats by default?
This has the added advantage that you don't have to
perform deletes in the correct RI order.
(though you will have to do a SET INTEGRITY afterwards)
OK

EDIT 2: Please see the following:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文