3

I want a quick way to delete all records relating to a particular 'master' record from both the 'master' table and all associated tables. This is primarily so that I can easily enter test records and then delete all trace of them, which would take a long time manually given that there are dozens of tables where the record could be referenced.

So, in summary, in any table which contains a column called AdmissionID, I want to delete all records where the AdmissionID is equal to a value I will specify. I thought I could do this quite easily. Here's my stored procedure:

ALTER PROCEDURE [Admin].[sp_RemoveByAdmissionID]

@admissionID int

AS
--Removes records from all tables relating the AdmissionID entered

DECLARE @loop INT
DECLARE @object sysname
DECLARE @cmdstring varchar(500)

IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL 
 BEGIN
  DROP TABLE #TEMP
 END

SELECT 
    TABLE_NAME
    ,ROW_NUMBER() OVER (ORDER BY TABLE_NAME) ROWID
INTO #TEMP
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE'

WHILE @loop <= (SELECT MAX(ROWID) FROM #TEMP)
  BEGIN
    SELECT @object = TABLE_NAME FROM #TEMP WHERE ROWID = @loop
        IF EXISTS (SELECT * FROM SYS.COLUMNS WHERE Name = 'AdmissionID' AND Object_ID = Object_ID(@object))
        BEGIN
            SET @cmdstring = 'DELETE FROM ' + @object + ' WHERE AdmissionID = ' + @admissionID
            Exec(@cmdstring)
        END    
  SET @loop += 1
  END

Unfortunately, executing this procedure doesn't delete any records from anywhere. I suspected the problem might be to do with my parameter not being enclosed in quotation marks in the line where I build up the cmdstring string, but even attempting to mitigate for this doesn't seem to have worked.

Any advice on where I'm going wrong, or if there's a simpler way to do this? I'd prefer not to use cascading deletes on my PK-FK relationships.


UPDATE Following the advice of Luv I found that his query does return a very nice list of the exact commands I want to use. I thought it'd be easy from there, but I still can't make this work. The new SP I'm trying is as follows:

ALTER PROCEDURE TEST

@admissionID VARCHAR(10)

AS

DECLARE @loop INT
DECLARE @cmd VARCHAR(500)


IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL 
BEGIN
DROP TABLE #TEMP
END

SELECT 'DELETE FROM '+ C.TABLE_NAME +' WHERE AdmissionID = '+@admissionID AS cmd
,ROW_NUMBER() OVER (ORDER BY 'DELETE FROM '+ C.TABLE_NAME +' WHERE AdmissionID = '+@admissionID) ROWID
INTO #TEMP
FROM INFORMATION_SCHEMA.COLUMNS C
INNER JOIN INFORMATION_SCHEMA.TABLES T on C.TABLE_NAME=T.TABLE_NAME
WHERE C.COLUMN_NAME='AdmissionID'
AND T.TABLE_TYPE='BASE TABLE'

WHILE @loop <= (SELECT MAX(ROWID) FROM #TEMP)
    BEGIN
SELECT @cmd = cmd 
FROM #TEMP
WHERE ROWID = @loop

EXEC(@cmd)      
SET @loop += 1
END
4

1 回答 1

4

Copy the result from the Below Query and Run the Query.

declare @yourvalue varchar
set @yourvalue=''
select 'DELETE FROM '+ C.TABLE_NAME +' WHERE AdmissionID = '+@yourvalue 
from INFORMATION_SCHEMA.COLUMNS C
INNER JOIN INFORMATION_SCHEMA.TABLES T on C.TABLE_NAME=T.TABLE_NAME
where C.COLUMN_NAME='AdmissionID'
and T.TABLE_TYPE='BASE TABLE'

You can even make an SP and execute Dynamically too

于 2013-05-15T15:31:27.680 回答