我有一个表ProjectLayerContent设计如下:
ContentOfContentID [INT]
我想要做的是在删除过程中,我想显示一个列表,其中包括如果要删除此项目图层内容将删除的内容。 这几乎就是我所涉及的,但我知道这些结果并不正确
DECLARE @ProjectLayerContentID INT = 1;
DECLARE @resTable TABLE (
ProjectLayerContentIDP int,
ProjLContentType nvarchar(100));
DECLARE @ProjectLayerContentIDRecursionParam int;
DECLARE @Type NVARCHAR(MAX);
DECLARE @resultString NVARCHAR(MAX) = '';
-- SELECT Project layer content children with recursion
-- SELECT the count of the result from the recursion of the children of the project layer content id passed with the sql parameter in the query
DECLARE ProjectLayerContentChildren_Cursor CURSOR FOR
SELECT ProjectLayerContentID, 'Child(ren)'
FROM ProjectLayerContent
WHERE ProjectLayerContentParentID = @ProjectLayerContentID
OPEN ProjectLayerContentChildren_Cursor
FETCH NEXT FROM ProjectLayerContentChildren_Cursor INTO @ProjectLayerContentIDRecursionParam, @Type
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO @resTable SELECT @ProjectLayerContentIDRecursionParam, @Type;
;WITH ProjectLayerContentTotalScopeChildren AS(
SELECT ProjectLayerContentID,CAST('Content(s) of Child(ren)' as varchar(259)) AS ProjLContentType
FROM ProjectLayerContent
WHERE ContentOfContentID = @ProjectLayerContentIDRecursionParam
UNION ALL
SELECT Scopechildren.ProjectLayerContentID, CAST('Children Content Of Content of Child(ren)' as varchar(259)) AS ProjLContentType
FROM ProjectLayerContent Scopechildren INNER JOIN
ProjectLayerContentTotalScopeChildren projLContents ON Scopechildren.ContentOfContentID = projLContents.ProjectLayerContentID
UNION ALL
SELECT children.ProjectLayerContentID, CAST('Child(ren) of Child(ren) of Child(ren)' as varchar(259)) AS ProjLContentType
FROM ProjectLayerContent children INNER JOIN
ProjectLayerContentTotalScopeChildren projLContents ON children.ProjectLayerContentParentID = projLContents.ProjectLayerContentID
)
INSERT INTO @resTable SELECT ProjectLayerContentID, ProjLContentType from ProjectLayerContentTotalScopeChildren
FETCH NEXT FROM ProjectLayerContentChildren_Cursor INTO @ProjectLayerContentIDRecursionParam, @Type
END
-- close the cursor
CLOSE ProjectLayerContentChildren_Cursor
DEALLOCATE ProjectLayerContentChildren_Cursor
-----------------------------------------------------------------------------------------------------------
-- SELECT Project layer content Scope children with recursion
DECLARE ProjectLayerContent_Cursor CURSOR FOR
SELECT ProjectLayerContentID, 'Content Of Content'
FROM ProjectLayerContent
WHERE ContentOfContentID = @ProjectLayerContentID
OPEN ProjectLayerContent_Cursor
FETCH NEXT FROM ProjectLayerContent_Cursor INTO @ProjectLayerContentIDRecursionParam, @Type
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO @resTable SELECT @ProjectLayerContentIDRecursionParam, @Type;
;WITH ProjectLayerContentTotalScopeContentOfContent AS(
SELECT ProjectLayerContentID,CAST('Children Content Of Content' as varchar(259)) AS ProjLContentType
FROM ProjectLayerContent
WHERE ContentOfContentID = @ProjectLayerContentIDRecursionParam
UNION ALL
SELECT Scopechildren.ProjectLayerContentID, CAST('Children Content Of Content of Children Content Of Content' as varchar(259)) AS ProjLContentType
FROM ProjectLayerContent Scopechildren INNER JOIN
ProjectLayerContentTotalScopeContentOfContent projLContents ON Scopechildren.ContentOfContentID = projLContents.ProjectLayerContentID
UNION ALL
SELECT children.ProjectLayerContentID, CAST('Children of Children Content Of Content' as varchar(259)) AS ProjLContentType
FROM ProjectLayerContent children INNER JOIN
ProjectLayerContentTotalScopeContentOfContent projLContents ON children.ProjectLayerContentParentID = projLContents.ProjectLayerContentID
)
INSERT INTO @resTable SELECT ProjectLayerContentID, ProjLContentType from ProjectLayerContentTotalScopeContentOfContent
FETCH NEXT FROM ProjectLayerContent_Cursor INTO @ProjectLayerContentIDRecursionParam, @Type
END
-- close the cursor
CLOSE ProjectLayerContent_Cursor
DEALLOCATE ProjectLayerContent_Cursor
--select the result to present it.
SELECT * FROM @resTable;
提前致谢。
答案 0 :(得分:0)
我发现这个解决方案可以根据需要获得所需的功能。
我创建了存储过程以首先获取此项目图层的所有子项,并创建了一个表来添加结果。因为如果您有一个INSERT INTO EXEC,那么INSERT INTO EXEC的第一个错误将无效存储过程链相互调用。它只适用于第一次,但其他时间会显示错误。
DECLARE @ProjectLayerContentID INT = 1;
DECLARE @ProjectLayerContentIDRecursionParam INT;
DECLARE @Type NVARCHAR(MAX);
DECLARE @resultString NVARCHAR(MAX) = '';
-------Create temp table to insert the results into it
CREATE TABLE #ResTable(
ProjectLayerContentIDP int,
ProjLContentType nvarchar(100));
然后我为所有孩子的select语句创建了一个游标,这个孩子的关系是该项目图层的子项,或者是它的内容。
-- SELECT Project layer content children with recursion
-- SELECT the count of the result from the recursion of the children of the project layer content id passed with the sql parameter in the query
DECLARE ProjectLayerContent_Cursor CURSOR FOR
SELECT ProjectLayerContentID, CASE WHEN ProjectLayerContentParentID = @ProjectLayerContentID THEN 'Child(ren)' ELSE 'Content(s) of Content(s)' END
FROM ProjectLayerContent
WHERE ProjectLayerContentParentID = @ProjectLayerContentID
OR ContentOfContentID = @ProjectLayerContentID
OPEN ProjectLayerContent_Cursor
FETCH NEXT FROM ProjectLayerContent_Cursor INTO @ProjectLayerContentIDRecursionParam, @Type
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #ResTable SELECT @ProjectLayerContentIDRecursionParam, @Type;
然后我将调用递归存储过程来获取每个当前项目层内容的chlidren和子项的内容。
Exec DeleteCheck_ProjectLayerContentChildren @ProjectLayerContentIDRecursionParam;
FETCH NEXT FROM ProjectLayerContent_Cursor INTO @ProjectLayerContentIDRecursionParam, @Type
END
-- close the cursor
CLOSE ProjectLayerContent_Cursor
DEALLOCATE ProjectLayerContent_Cursor
在此部分,我们将选择结果,然后从数据库服务器中删除临时表。
--select the result to present it.
SELECT @resultString = @resultString + '<br/><u>' + CONVERT(NVARCHAR(MAX), Count(ProjectLayerContentIDP)) + '</u> ' + ProjLContentType
FROM #ResTable
GROUP BY ProjLContentType;
SELECT @resultString;
DROP TABLE #ResTable
以下是我们在上一个查询中已经调用过的递归存储过程
CREATE PROCEDURE [dbo].[DeleteCheck_ProjectLayerContentChildren]
@ProjectLayerContentID INT
AS
BEGIN
DECLARE @ProjectLayerContentIDRecursionParam INT;
DECLARE @Type NVARCHAR(MAX);
-- SELECT Project layer content children with recursion
-- SELECT the count of the result from the recursion of the children of the project layer content id passed with the sql parameter in the query.
注意这里我们将Local添加到光标的减速中,因为它会显示创建具有相同名称的光标的错误
DECLARE ProjectLayerContentChildren_Cursor CURSOR LOCAL FOR
SELECT ProjectLayerContentID, CASE WHEN ProjectLayerContentParentID = @ProjectLayerContentID THEN 'Child(ren) of Child(ren)' ELSE 'Child(ren) Content(s) of Content(s)' END
FROM ProjectLayerContent
WHERE ProjectLayerContentParentID = @ProjectLayerContentID
OR ContentOfContentID = @ProjectLayerContentID
这个查询的大部分内容与前一个查询相同,但这是针对项目图层内容子项的子项计数,我们不再创建结果表,因为它已经创建,然后我们只需添加结果,我们就拥有了所需的功能,您可以将它应用于两三个以上的自我关系。
OPEN ProjectLayerContentChildren_Cursor
FETCH NEXT FROM ProjectLayerContentChildren_Cursor INTO @ProjectLayerContentIDRecursionParam, @Type
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #ResTable SELECT @ProjectLayerContentIDRecursionParam, @Type;
Exec DeleteCheck_ProjectLayerContentChildren @ProjectLayerContentIDRecursionParam
FETCH NEXT FROM ProjectLayerContentChildren_Cursor INTO @ProjectLayerContentIDRecursionParam, @Type
END
-- close the cursor
CLOSE ProjectLayerContentChildren_Cursor
DEALLOCATE ProjectLayerContentChildren_Cursor
END