我试图实现的是以下内容。 当我删除一条记录时,我想检查是否有任何FK关系,并且它需要递归。这样我可以显示与您想要删除的记录相关的所有记录的列表。检索所有外键及其记录
所以嵌套链接的一个小例子 项目1 - >第1阶段 - >块1 - > ..
所以,当我尝试删除项目1我要得到你需要的物品清单删除第一: 阶段1 块1 ....
我想与一个存储过程,需要一个ID和一个表名(格式[CHEMA] [表名]),发现所有这些链接的记录要做到这一点。
我遇到的问题是递归部分。 这里是我到目前为止的代码:
ALTER PROCEDURE core.usp_CanBeDeleted
@entityId int,
@entityName nvarchar(250)
AS
BEGIN
DECLARE @NumberRecords int, @RowCount int
DECLARE @childId int
DECLARE @query nvarchar(max)
DECLARE @eName nvarchar(250) , @keyName nvarchar(250)
DECLARE @columnName nvarchar(250)
DECLARE @keys TABLE(
RowID int IDENTITY(1, 1),
name nvarchar(250),
entityName nvarchar(250),
columnName nvarchar(250)
)
if not exists (select * from sysobjects where name='partialResults' and xtype='U')
BEGIN
CREATE TABLE partialResults(
RowID int IDENTITY(1, 1),
id int,
parentId int,
name nvarchar(250),
FK_name nvarchar(250)
)
END
DECLARE @recusiveResults TABLE(
RowID int,
id int,
parentId int,
name nvarchar(250),
FK_name nvarchar(250)
)
DECLARE @results TABLE(
RowID int,
id int,
parentId int,
name nvarchar(250),
FK_name nvarchar(250)
)
SET @RowCount = 1
-- get all FK's of the entity
INSERT INTO @keys
SELECT name, '[' + OBJECT_SCHEMA_NAME(parent_object_id) + '].[' + OBJECT_NAME(parent_object_id)+ ']',cu.column_name
from sys.foreign_keys k
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
ON k.name = CU.CONSTRAINT_NAME
where k.referenced_object_id = OBJECT_ID(@entityName)
-- set variable to number of records in temp table
SET @NumberRecords = @@ROWCOUNT
-- loop through the FK's an get all linked entities
WHILE(@RowCount <= @NumberRecords)
BEGIN
SELECT @keyName = name, @eName = entityName, @columnName = columnName
FROM @keys
WHERE RowId = @RowCount
-- get all FK information
SET @query = 'INSERT INTO partialResults(FK_name, name, id, parentId)'
+ ' SELECT ''' + @keyName + ''','''+ @eName + ''',' + 'id,' + cast(@entityId as varchar(25)) + ' as parentid'
+ ' FROM ' [email protected]
+ ' WHERE id in '
+ ' (SELECT ' + @columnName
+ ' FROM ' + @entityName
+ ' WHERE id = ' + cast(@entityId as varchar(25))
+ ')'
--print @query
EXEC (@query)
SET @RowCount = @RowCount + 1
END
-- rest number of records
SET @RowCount = 1
SELECT @NumberRecords = count(id)
FROM partialResults
-- save partialResults
INSERT INTO @results--(FK_name, name, id, parentId)
SELECT *--FK_name, name, id, parentId
FROM partialResults
DELETE FROM partialResults
WHILE(@RowCount <= @NumberRecords)
BEGIN
-- select next row
SELECT @childId = id, @eName = name
FROM @results
WHERE RowId = @RowCount
INSERT INTO @recusiveResults
EXEC core.usp_CanBeDeleted @childId, @eName
SET @RowCount = @RowCount + 1
END
INSERT INTO @results
SELECT *
FROM @recusiveResults
if exists (select * from sysobjects where name='partialResults' and xtype='U')
BEGIN
-- remove temp tables
DROP TABLE partialResults
END
-- return results
SELECT *
FROM @results
END
GO
问题就出在这里:
INSERT INTO @recusiveResults
EXEC core.usp_CanBeDeleted @childId, @eName
Apparantly不能嵌套插入EXEC。然而,我真的没有看到任何其他的方式来做到这一点。 我试过把它转换成一个函数,但后来还有其他问题,如动态查询。
任何帮助将大大apreciated。
谢谢塞巴斯蒂安,我会试试看。 开始了很简单,但我不断增加的东西来尝试和解决问题。 我想我会需要一个内部和外部程序,但有点失去了我的方式:-) –
它的工作。我仍然需要额外的#partialResults临时表来避免无限循环。 否则,我会将结果添加到结果中,循环播放结果并在每个循环中添加更多结果到结果......这不会是最好的想法。 无论如何,如果有人对最终代码感兴趣,我会在稍后发布,因为我现在没有太多时间。 –