PlotDirector/PlotLine/Sql/195_LocationReparent.sql

54 lines
3.0 KiB
Transact-SQL

-- Change only hierarchy fields, preserving location details and aliases.
CREATE OR ALTER PROCEDURE dbo.Location_Reparent
@ProjectID int,
@LocationID int,
@ParentLocationID int,
@ExpectedParentLocationID int = NULL,
@UserID int = NULL
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
DECLARE @LockedProjectID int, @OldParentID int, @Name nvarchar(200), @ParentName nvarchar(200);
SELECT @LockedProjectID=ProjectID FROM dbo.Projects WITH (UPDLOCK,HOLDLOCK) WHERE ProjectID=@ProjectID AND IsArchived=0;
IF @LockedProjectID IS NULL OR @UserID IS NULL OR NOT EXISTS
(SELECT 1 FROM dbo.ProjectUserAccess WHERE ProjectID=@ProjectID AND UserID=@UserID AND IsActive=1)
THROW 51000, 'You do not have access to this project.', 1;
SELECT @Name=LocationName,@OldParentID=ParentLocationID FROM dbo.Locations WITH (UPDLOCK,HOLDLOCK)
WHERE LocationID=@LocationID AND ProjectID=@ProjectID AND IsArchived=0;
SELECT @ParentName=LocationName FROM dbo.Locations WITH (UPDLOCK,HOLDLOCK)
WHERE LocationID=@ParentLocationID AND ProjectID=@ProjectID AND IsArchived=0;
IF @Name IS NULL OR @ParentName IS NULL
THROW 51000, 'Choose active locations from the same project.', 1;
IF ISNULL(@OldParentID,0)<>ISNULL(@ExpectedParentLocationID,0)
THROW 51000, 'The parent has changed since this page was loaded. Review the updated tree and try again.', 1;
IF @OldParentID=@ParentLocationID
THROW 51000, 'This location already has that parent.', 1;
DECLARE @AncestorID int=@ParentLocationID;
DECLARE @Visited TABLE (LocationID int PRIMARY KEY);
WHILE @AncestorID IS NOT NULL
BEGIN
IF @AncestorID=@LocationID OR EXISTS (SELECT 1 FROM @Visited WHERE LocationID=@AncestorID)
THROW 51000, 'A location cannot be its own parent or be moved beneath one of its descendants.', 1;
INSERT @Visited VALUES (@AncestorID);
DECLARE @NextAncestorID int=NULL;
SELECT @NextAncestorID=ParentLocationID FROM dbo.Locations WITH (UPDLOCK,HOLDLOCK) WHERE LocationID=@AncestorID;
SET @AncestorID=@NextAncestorID;
END;
UPDATE dbo.Locations SET ParentLocationID=@ParentLocationID,UpdatedDate=SYSUTCDATETIME(),
ModifiedDateUTC=SYSUTCDATETIME(),ModifiedByUserID=@UserID WHERE LocationID=@LocationID;
DECLARE @Description nvarchar(1000)=CONCAT(N'Parent changed from ',
COALESCE((SELECT LocationName FROM dbo.Locations WHERE LocationID=@OldParentID),N'top level'),N' to ',@ParentName,N'.');
EXEC dbo.ProjectAudit_Record @ProjectID=@ProjectID,@UserID=@UserID,@ActivityType=N'Updated',
@EntityType=N'Location',@EntityID=@LocationID,@EntityName=@Name,@Description=@Description;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF XACT_STATE()<>0 ROLLBACK TRANSACTION;
THROW;
END CATCH;
END;
GO