在 DB2 联合数据库(基于远程服务器和昵称)中,我需要清理模型并从另一个数据库重新创建它。我需要删除除那些服务器和昵称之外的所有数据库对象。
我知道如何从 SYSCAT 模式中检索对象列表。现在我需要在每个上运行 DROP 语句。显然,依赖关系会阻碍。
蛮力方法是循环运行 DROP,直到全部成功,但根据顺序(幸运与否),可能需要很长时间。
您是否知道一种有效排序 DROP 语句的方法,以便删除的总时间尽可能短?
不期望有完美的解决方案。一个相当聪明的解决方案就足够了。
谢谢
在 DB2 联合数据库(基于远程服务器和昵称)中,我需要清理模型并从另一个数据库重新创建它。我需要删除除那些服务器和昵称之外的所有数据库对象。
我知道如何从 SYSCAT 模式中检索对象列表。现在我需要在每个上运行 DROP 语句。显然,依赖关系会阻碍。
蛮力方法是循环运行 DROP,直到全部成功,但根据顺序(幸运与否),可能需要很长时间。
您是否知道一种有效排序 DROP 语句的方法,以便删除的总时间尽可能短?
不期望有完美的解决方案。一个相当聪明的解决方案就足够了。
谢谢
您可能希望查看每个表的引用(您可以syscat.references
根据http://www.ibm.com/developerworks/data/library/techarticle/dm-0401melnyk/进行操作)并自己构建依赖关系树(应该是可行的,例如使用临时表,如果你仅限于 sql)。然后你可能会从那棵树的底部掉下来。
所以,基本上,我对你的问题的回答是,为了快速完成,只需在删除之前根据它们之间的引用对表进行排序。由于不应该有任何依赖循环,因此您应该始终能够选择一个未引用的表。放下它并重复。
您可能还希望看到这个(类似的?)问题:DB2 cascade delete command? 如果您想先删除数据。
如果我在某些时候错了,请纠正。这个答案基于我对其他数据库的经验,因此它可能不完全适合 DB2。虽然它应该工作;)
此查询能够根据语句所依赖的元素总数对语句进行排序。生成的顺序几乎没有故障,“蛮力”方法的第二遍仅包含少数对象(要删除的数千个对象中)。
问题,太慢了。。。
编辑:查询中有一个错字,使它返回或多或少正确的数据,但非常非常慢。
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(*)
我没有 DB2 的直接解决方案,但我可以建议:
A) 在 Microsoft SQL Server 2008 中,已经解决了删除(而不是 DROP)有关外键顺序的表的问题,在此链接:
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:请参阅以下内容: