I have about 50 tables with created-by and changed-by referencing the user table. When I want to delete the user, I would like to create a list of what tables this user has data in, so one can go delete/edit everything belonging to said user. Is there any way of doing this in SQL?
-
check out my answer it does what you need – KM. Apr 06 '09 at 12:58
6 Answers
You can use cascaded delete.

- 317
- 1
- 5
-
-
No it won't create a list, it will just *DO* what you wanted to do in the first place :D – Ian G Apr 06 '09 at 10:19
-
-
This will not work, since what I want is to create a list so the user can determine weather to delete the data or move it to another user, or simply mark the user as inactive instead of deleting it. Doing a on cascade delete (or even set null) would be VERY bad in my app. – devzero Apr 06 '09 at 12:36
Not exactly sure of what you're going for here..
If you want a list of foreign keys referencing a table try this question How can I list all foreign keys referencing a given table in SQL Server?
-
It's pretty much what I want, except I need to do a loop after this query to check what tables/fk's actually contains data for a given user. I guess the simplest way of doing that is by using .net to loop through the result set and generate a query for each. – devzero Apr 06 '09 at 12:34
SQL 2005+ provides a number of system views like sys.tables and sys.foreign_key_columns which may help you.
SELECT
pt.name AS ParentTable,
pc.name AS ParentColumn,
rt.name AS ReferencedTable,
rc.name AS ReferencedColumn
FROM sys.foreign_key_columns fkc
INNER JOIN sys.tables pt ON pt.object_id = fkc.parent_object_id
INNER JOIN sys.columns pc ON pc.column_id = fkc.parent_column_id AND
pc.object_id = fkc.parent_object_id
INNER JOIN sys.tables rt ON rt.object_id = fkc.referenced_object_id
INNER JOIN sys.columns rc ON rc.column_id = fkc.referenced_column_id AND
rc.object_id = fkc.referenced_object_id

- 807
- 4
- 7
this will list all tables where your ID exists:
DECLARE @Query varchar(1000)
DECLARE @MaxRow int
DECLARE @CurrentRow int
DECLARE @CurrentTable varchar(500)
DECLARE @UserID int
SET @UserID=???
CREATE TABLE #Rows
(
RowID int not null primary key identity(1,1)
,TableWithForeignKey varchar(500)
)
CREATE TABLE #Temp
(
RowValue int
)
INSERT INTO #Rows
(TableWithForeignKey )
select
t.name as TableWithForeignKey --, fk.constraint_column_id as FK_PartNo , c.name as ForeignKeyColumn
from sys.foreign_key_columns as fk
inner join sys.tables as t on fk.parent_object_id = t.object_id
inner join sys.columns as c on fk.parent_object_id = c.object_id and fk.parent_column_id = c.column_id
where fk.referenced_object_id = (select object_id from sys.tables where name = '????????')
--order by TableWithForeignKey, FK_PartNo
SELECT @MaxRow=@@ROWCOUNT
SET @CurrentRow=0
SELECT * FROM #Rows
WHILE @CurrentRow<@MaxRow
BEGIN
SET @CurrentRow=@CurrentRow+1
SELECT @CurrentTable=TableWithForeignKey FROM #Rows WHERE RowID=@CurrentRow
--SET @Query='DELETE FROM '+@CurrentTable+' WHERE UserID='+CONVERT(varchar(20),@UserID)
SET @Query='SELECT COUNT(*) FROM '+@CurrentTable+' WHERE YourIDhere='+CONVERT(varchar(20),@UserID)
PRINT @Query
INSERT INTO #Temp
EXECUTE (@Query)
IF NOT EXISTS (SELECT RowValue FROM #Temp WHERE RowValue>0)
BEGIN
PRINT 'no matches found'
DELETE #Rows WHERE RowID=@CurrentRow
END
ELSE
BEGIN
PRINT 'matches found!!'
END
DELETE #Temp
END
--list all tables where the ID exists
SELECT * FROM #Rows

- 101,727
- 34
- 178
- 212
-
This is essentialy correct, but you need to put [] table names, and YourIDhere should be dynamic. – devzero Apr 06 '09 at 12:44
A couple of methods for finding the tables that reference your User table through foreign key relationships have been posted and here's another: http://www.sqlservercurry.com/2009/03/simple-stored-procedure-to-find-foreign.html
Once you get the list of tables, you're going to have to write the SQL to determine which tables have records for a specific user. There's no way around that. Since the queries will all look the same, you could paste the table list into Excel, use a formula to build the queries, then paste the queries back into SSMS.

- 48,427
- 16
- 81
- 117