Is there a efficient way to delete every view/function/table/sp from a database?

StackOverflow https://stackoverflow.com/questions/6014919

  •  14-11-2019
  •  | 
  •  

Question

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

Was it helpful?

Solution 2

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

OTHER TIPS

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 ;)

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top