Tuesday, January 4, 2011

Deleting SDE left over tables

 

Warning: Do this only if you don't have any other choice!

So I got to a stage in my code where SQL Server Management shown:

image

And my test showed the following error:

ERROR: Table already registered [Microsoft SQL Server Native Client 10.0: Violation of UNIQUE KEY constraint 'registry_uk2'. Cannot insert duplicate key in object 'sde.SDE_table_registry'. The duplicate key value is (CARS, GIS, FLUENTMIGRATOR).] [FluentMigrator.GIS.CARS]

What does it mean?

It means I deleted a table with "DROP TABLE" where I needed to use ArcObjects/ArcCatalog and all I got from it is this lousy T shirt… Just without the T shirt…

So it should come as no surprise that SDE stores the metadata of their feature/table layers, and when deleting tables they get deleted from it.

The SDE Database table structure:

image

(At least on my computer)

From the Exception table - SDE_table_registry contains:

image

See line 7 – that’s our CARS non layer table

Lets delete those rows.

But don't think we are done, there is still the column registry table - SDE_column_registry:

image

Lets delete those rows as well.

 

For feature Layers the situation is a bit more complex:

For example we look at REGIONS table:

At SDE_table_registry:

image

At SDE_column_registry:

image

At SDE_layers:

image

At SDE_geometry_columns:

image

(Don't worry we are not yet done!)

At GDB_ITEMRELATIONSHIPS if we query:

SELECT     sde.GDB_ITEMS.*, sde.GDB_ITEMRELATIONSHIPS.*

FROM         sde.GDB_ITEMRELATIONSHIPS INNER JOIN

                      sde.GDB_ITEMS ON sde.GDB_ITEMRELATIONSHIPS.DestID = sde.GDB_ITEMS.UUID

we get some items from GDB_ITEMS (see next item).

At GDB_ITEMS:

image

And

And we must not forget the SPs – in our database we need to delete the SPs whose number is not used by any table (see SDE – A look at the layer table structure).

 

And at least according to the profiler when delete another feature layer be sure to look at SDE_metadata.

 

To Sum it all together – SDE sucks!

But now here is a script I wrote (I am not a DBA so there might be mistakes) that does all this deletes (be sure to replace all the grey matter):

declare @LayerId int

declare @SdeLockId int

declare @DatabaseName varchar(32)

declare @TableName varchar(128)

declare @OwnerName varchar(32)

 

set @DatabaseName = 'FLUENTMIGRATOR'

set @TableName = 'REGIONS'

set @OwnerName = 'GIS'

 

 

--Getting the layer id

Select @LayerId=layer_id

from sde.sde.SDE_layers

where database_name=@DatabaseName and table_name=@TableName and owner=@OwnerName

--Getting the lock id

Select @SdeLockId= sde_id

from sde.sde.SDE_layer_locks

where layer_id=@LayerId

 

 

DELETE FROM sde.GDB_ITEMRELATIONSHIPS

WHERE DestID in (SELECT UUID FROM sde.GDB_ITEMS WHERE Name = 'FluentMigrator.GIS.REGIONS')

DELETE FROM sde.GDB_ITEMS WHERE Name = 'FluentMigrator.GIS.REGIONS'

DELETE FROM sde.SDE_column_registry WHERE owner=@OwnerName and table_name=@TableName and database_name=@DatabaseName

DELETE FROM sde.SDE_geometry_columns WHERE f_table_catalog=@DatabaseName and f_table_schema=@OwnerName and f_table_name = @TableName

DELETE FROM sde.SDE_layers WHERE database_name=@DatabaseName and owner=@OwnerName and table_name = @TableName

DELETE FROM sde.SDE_table_registry WHERE database_name=@DatabaseName and owner=@OwnerName and table_name = @TableName

 

exec sde.sde.SDE_layer_def_delete @LayerId

exec sde.sde.SDE_geocol_def_delete @DatabaseName,@OwnerName,@TableName,N'SHAPE'

 

exec sde.sde.SDE_layer_lock_def_delete @SdeLockId,@LayerId,'N'

exec sde.sde.SDE_layer_lock_def_delete_user @SdeLockId

exec sde.sde.SDE_state_lock_def_delete_user @SdeLockId

exec sde.sde.SDE_table_lock_def_delete_user @SdeLockId

exec sde.sde.SDE_object_lock_def_delete_user @SdeLockId

exec sde.sde.SDE_pinfo_def_delete @SdeLockId

 

This seems to work for both regular tables and feature layers.

If someone has a better suggestions for this script please let me know.

 

 

del.icio.us Tags: ,,,,,
IceRocket Tags: ,,,,,