db中存在主键人力human,由于日积月累的数据,再加上前期设置主外键的混乱,有许多的子表里的键都属于human表中humanID,loginID,humanMonitorID的外键,并且有些表根本没有建立外键但值却存放着外键值。
现在要彻底删除某些主表的值,但在删除前需要找到这些值在其它表引用的数据有多行,所以就有了下面的解决方法:
IF OBJECT_ID ('p_JCXX_HumanQueryHumanID') IS NOT NULL DROP PROCEDURE p_JCXX_HumanQueryHumanID GO
-- 传入的主健ID,返回的是引用行数 CREATE PROCEDURE p_JCXX_HumanQueryHumanID @humanID nvarchar(128), @totalCount INT OUTPUT AS SET NOCOUNT OFF DECLARE @num INT; DECLARE @sql NVARCHAR(512); DECLARE @ptab NVARCHAR(50); DECLARE @pcol NVARCHAR(50); DECLARE @ftab NVARCHAR(50); DECLARE @fcol NVARCHAR(50); DECLARE @hmid NVARCHAR(50); -- 人力监控ID DECLARE @lgid NVARCHAR(50); -- 人力登陆ID CREATE TABLE #T( ptab NVARCHAR(128), pcol NVARCHAR(128), ftab NVARCHAR(128), fcol NVARCHAR(128) ); SELECT @hmid=humanMonitorID, @lgid=loginID FROM Human WHERE humanID = @humanID; INSERT INTO #T SELECT rtable.name ptab, cn.name pcol, ftable.name ftab, fkcn.name fcol FROM sysforeignkeys INNER JOIN sysobjects ftable ON sysforeignkeys.fkeyid = ftable.id INNER JOIN sysobjects rtable ON sysforeignkeys.rkeyid = rtable.id INNER JOIN syscolumns fkcn ON sysforeignkeys.fkeyid = fkcn.id AND sysforeignkeys.fkey = fkcn.colid INNER JOIN syscolumns cn ON sysforeignkeys.rkeyid = cn.id AND sysforeignkeys.rkey = cn.colid WHERE rtable.name IN ('Human') -- 主表名,主列名,外表名,外列名(数据库未建立外键,但数值是属于外健,手动指定) INSERT INTO #T (ptab,pcol,ftab,fcol) SELECT 'Human','humanID','MonitorModifyHistory','humanID' UNION SELECT 'Human','humanID','TypicalPart','designer'; BEGIN DECLARE datas CURSOR FOR SELECT * FROM #T OPEN datas; FETCH next FROM datas INTO @ptab,@pcol,@ftab,@fcol WHILE @@FETCH_STATUS=0 BEGIN IF @pcol ='humanID' SET @sql = 'select @i=count(' + @fcol + ') from [' + @ftab + '] WHERE ' + @fcol + ' = '''+ @humanID + ''''; IF @pcol ='loginID' SET @sql = 'select @i=count(' + @fcol + ') from [' + @ftab + '] WHERE ' + @fcol + ' = '''+ @lgid + ''''; IF @pcol ='humanMonitorID' SET @sql = 'select @i=count(' + @fcol + ') from [' + @ftab + '] WHERE ' + @fcol + ' = '''+ @hmid + ''''; IF @sql IS NOT NULL BEGIN EXEC sp_executesql @sql, N'@i int output',@num OUTPUT IF @num >0 SET @totalCount = @totalCount + @num; END; FETCH next FROM datas INTO @ptab,@pcol,@ftab,@fcol END; CLOSE datas; DEALLOCATE datas;; END