SET NUMERIC_ROUNDABORT OFF GO SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT, QUOTED_IDENTIFIER, ANSI_NULLS ON GO SET XACT_ABORT ON GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE GO UPDATE REF_LINK_TABLES SET ReadOnly = 0 WHERE Table_Name = 'LNK_JOB_CONTRACT_VIRTUAL' GO DROP FUNCTION [dbo].[fn_Job_Contract] GO SET ANSI_NULLS OFF GO CREATE FUNCTION [dbo].[fn_Job_Contract](@Left_Join int, @Right_Join int) RETURNS TABLE AS RETURN ( WITH OuterQuery AS ( SELECT Left_Join, Right_Join, Start_Date, End_Date , ROW_NUMBER() OVER (PARTITION BY Right_Join, ChildGrp ORDER BY Start_Date) AS ChildRowASC , ROW_NUMBER() OVER (PARTITION BY Right_Join, ChildGrp ORDER BY Start_Date DESC) AS ChildRowDESC , DENSE_RANK() OVER (PARTITION BY Right_Join ORDER BY ChildGrp) as ChildGrp FROM ( SELECT Left_Join, Right_Join, Start_Date, End_Date , ParentRows - RANK() OVER (PARTITION BY Right_Join, ChildSeq, Left_Join ORDER BY Start_Date) as ChildGrp FROM ( SELECT CAST(ISNULL(Job, 0) AS int) AS Left_Join , Entity_Id AS Right_Join , Entity_Start_Date AS Start_Date , Entity_End_Date AS End_Date , ROW_NUMBER() OVER (PARTITION BY Entity_Id ORDER BY Entity_Start_Date) AS ParentRows , ROW_NUMBER() OVER (PARTITION BY Entity_Id ORDER BY Entity_Start_Date) - ROW_NUMBER() OVER (PARTITION BY Entity_Id, CAST(Job AS int) ORDER BY Entity_Start_Date) as ChildSeq FROM [dbo].[DT_CONTRACT] OuterQuery WHERE NOT CAST(ISNULL(Job, 0) AS int) = 0 ) f2 ) f1 ) SELECT ROW_NUMBER() OVER (ORDER BY Right_Join, Start_Date) AS Ndx , Left_Join , Right_Join , Start_Date , End_Date FROM (SELECT DISTINCT OuterQuery.Left_Join , OuterQuery.Right_Join , COALESCE(DATEADD(d, 1, t2.End_Date), t3.Start_Date, OuterQuery.Start_Date) AS Start_Date , COALESCE(DATEADD(d, -1, t4.Start_Date), t5.End_Date) AS End_Date FROM OuterQuery LEFT OUTER JOIN OuterQuery t2 ON t2.Right_Join = OuterQuery.Right_Join AND t2.ChildGrp = OuterQuery.ChildGrp - 1 AND t2.ChildRowDESC = 1 LEFT OUTER JOIN OuterQuery t3 ON t3.Right_Join = OuterQuery.Right_Join AND t3.ChildGrp = OuterQuery.ChildGrp AND t3.ChildRowASC = 1 LEFT OUTER JOIN OuterQuery t4 ON t4.Right_Join = OuterQuery.Right_Join AND t4.ChildGrp = OuterQuery.ChildGrp + 1 AND t4.ChildRowASC = 1 LEFT OUTER JOIN OuterQuery t5 ON t5.Right_Join = OuterQuery.Right_Join AND t5.ChildGrp = OuterQuery.ChildGrp AND t5.ChildRowDESC = 1 WHERE (OuterQuery.Left_Join = @Left_Join OR @Left_Join IS NULL) AND (OuterQuery.Right_Join = @Right_Join OR @Right_Join IS NULL) ) a ) GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER OFF GO ALTER TRIGGER [dbo].[UpdateJobVirtualLinks] ON [dbo].[DT_JOB] FOR INSERT, UPDATE, DELETE AS BEGIN SET NOCOUNT ON DECLARE @ChangeThreshold int DECLARE @RefreshAll bit DECLARE @Processed nvarchar(1024) DECLARE @CurrentID nvarchar(32) DECLARE @AlreadyDone bit DECLARE @Entity_Id int DECLARE @PayID int DECLARE @ContractID int DECLARE @JobLoop int DECLARE @FullRecalc bit DECLARE @Action as char(1) DECLARE @Cinfo VARBINARY(128) DECLARE @PayPayGrade smallint --this session flag is used to disable a trigger temporarily SELECT @Cinfo = Context_Info() IF @Cinfo = 0x55555 RETURN SET @Action = (CASE WHEN EXISTS(SELECT * FROM INSERTED) AND EXISTS(SELECT * FROM DELETED) THEN 'U' -- Set Action to Updated. WHEN EXISTS(SELECT * FROM INSERTED) THEN 'I' -- Set Action to Insert. WHEN EXISTS(SELECT * FROM DELETED) THEN 'D' -- Set Action to Deleted. ELSE NULL -- Skip. It may have been a "failed delete". END) IF (@Action IS NULL) RETURN; IF (@Action = 'I' OR @Action = 'D') SET @FullRecalc = 1 IF (@Action = 'U') --Entity fields always recalc IF (UPDATE(Entity_Id) OR UPDATE(Entity_Start_Date) OR UPDATE(Entity_End_Date)) SET @FullRecalc = 1 SET @PayPayGrade = ISNULL((SELECT TOP 1 Enabled FROM REF_LINK_TABLES WHERE Table_name = 'LNK_PAY_PAY_GRADE_VIRTUAL' AND CustomisationID IN (SELECT CustomisationID FROM REF_CUSTOMISATIONS WHERE Enabled =1) ORDER BY CustomisationID DESC), 0) DECLARE @PayChangeCount int SET @ChangeThreshold = 5 IF ((SELECT DISTINCT COUNT(Entity_Id) FROM INSERTED) + (SELECT DISTINCT COUNT(Entity_Id) FROM DELETED) > @ChangeThreshold) SET @RefreshAll = 1 IF (@RefreshAll = 1) BEGIN IF (@FullRecalc = 1) BEGIN DELETE FROM LNK_JOB_CONTRACT_VIRTUAL DBCC CHECKIDENT (LNK_JOB_CONTRACT_VIRTUAL, RESEED, 1) INSERT INTO LNK_JOB_CONTRACT_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Contract(NULL, NULL) END IF (@FullRecalc = 1 OR UPDATE(Location)) BEGIN DELETE FROM LNK_JOB_LOCATION_VIRTUAL DBCC CHECKIDENT (LNK_JOB_LOCATION_VIRTUAL, RESEED, 1) INSERT INTO LNK_JOB_LOCATION_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Location(NULL, NULL) DELETE FROM LNK_CONTRACT_LOCATION_VIRTUAL DBCC CHECKIDENT (LNK_CONTRACT_LOCATION_VIRTUAL, RESEED, 1) INSERT INTO LNK_CONTRACT_LOCATION_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Contract_Location(NULL, NULL) END IF (@FullRecalc = 1 OR UPDATE(Department)) BEGIN DELETE FROM LNK_JOB_DEPARTMENT_VIRTUAL DBCC CHECKIDENT (LNK_JOB_DEPARTMENT_VIRTUAL, RESEED, 1) INSERT INTO LNK_JOB_DEPARTMENT_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Department(NULL, NULL) DELETE FROM LNK_CONTRACT_DEPARTMENT_VIRTUAL DBCC CHECKIDENT (LNK_CONTRACT_DEPARTMENT_VIRTUAL, RESEED, 1) INSERT INTO LNK_CONTRACT_DEPARTMENT_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Contract_Department(NULL, NULL) END IF (@FullRecalc = 1 OR UPDATE(Pay_Grade)) BEGIN DELETE FROM LNK_JOB_PAY_GRADE_VIRTUAL DBCC CHECKIDENT (LNK_JOB_PAY_GRADE_VIRTUAL, RESEED, 1) INSERT INTO LNK_JOB_PAY_GRADE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Pay_Grade(NULL, NULL) DELETE FROM LNK_PAY_PAY_GRADE_VIRTUAL DBCC CHECKIDENT (LNK_PAY_PAY_GRADE_VIRTUAL, RESEED, 1) INSERT INTO LNK_PAY_PAY_GRADE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Pay_Pay_Grade(NULL, NULL) END IF (@FullRecalc = 1 OR UPDATE(Contract_Type)) BEGIN DELETE FROM LNK_JOB_CONTRACT_TYPE_VIRTUAL DBCC CHECKIDENT (LNK_JOB_CONTRACT_TYPE_VIRTUAL, RESEED, 1) INSERT INTO LNK_JOB_CONTRACT_TYPE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Contract_Type(NULL, NULL) DELETE FROM LNK_CONTRACT_CONTRACT_TYPE_VIRTUAL DBCC CHECKIDENT (LNK_CONTRACT_CONTRACT_TYPE_VIRTUAL, RESEED, 1) INSERT INTO LNK_CONTRACT_CONTRACT_TYPE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Contract_Contract_Type(NULL, NULL) END END ELSE BEGIN SET @Processed = '' DECLARE ChangesCursor CURSOR LOCAL FAST_FORWARD FOR SELECT DISTINCT Entity_Id FROM INSERTED WHERE Entity_Id > 0 UNION SELECT DISTINCT Entity_Id FROM DELETED WHERE Entity_Id > 0 OPEN ChangesCursor FETCH NEXT FROM ChangesCursor INTO @Entity_Id SET @JobLoop = @@FETCH_STATUS WHILE @JobLoop = 0 BEGIN SET @CurrentID = ' ' + CAST(@Entity_Id as nvarchar) + ' ' SET @AlreadyDone = CASE (PATINDEX(@CurrentID, @Processed)) WHEN 0 THEN 0 ELSE 1 END IF @AlreadyDone = 0 BEGIN IF (@FullRecalc = 1) BEGIN DELETE FROM LNK_JOB_CONTRACT_VIRTUAL WHERE Left_Join = @Entity_Id INSERT INTO LNK_JOB_CONTRACT_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Contract(@Entity_Id, NULL) END IF (@FullRecalc = 1 OR UPDATE(Location)) BEGIN DELETE FROM LNK_JOB_LOCATION_VIRTUAL WHERE Left_Join = @Entity_Id INSERT INTO LNK_JOB_LOCATION_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Location(@Entity_Id, NULL) END IF (@FullRecalc = 1 OR UPDATE(Department)) BEGIN DELETE FROM LNK_JOB_DEPARTMENT_VIRTUAL WHERE Left_Join = @Entity_Id INSERT INTO LNK_JOB_DEPARTMENT_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Department(@Entity_Id, NULL) END IF (@FullRecalc = 1 OR UPDATE(Pay_Grade)) BEGIN DELETE FROM LNK_JOB_PAY_GRADE_VIRTUAL WHERE Left_Join = @Entity_Id INSERT INTO LNK_JOB_PAY_GRADE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Pay_Grade(@Entity_Id, NULL) END IF (@FullRecalc = 1 OR UPDATE(Contract_Type)) BEGIN DELETE FROM LNK_JOB_CONTRACT_TYPE_VIRTUAL WHERE Left_Join = @Entity_Id INSERT INTO LNK_JOB_CONTRACT_TYPE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Job_Contract_Type(@Entity_Id, NULL) END --5.11 made virtuals between contract and dept/loc etc DECLARE ContractCursor CURSOR LOCAL FAST_FORWARD FOR SELECT DISTINCT DTC.Entity_Id FROM DT_CONTRACT DTC WHERE CAST(DTC.Job as int) = @CurrentID OPEN ContractCursor FETCH NEXT FROM ContractCursor INTO @ContractID WHILE @@FETCH_STATUS = 0 BEGIN IF (@FullRecalc = 1 OR UPDATE(Location)) BEGIN DELETE FROM LNK_CONTRACT_LOCATION_VIRTUAL WHERE Left_Join = @ContractID INSERT INTO LNK_CONTRACT_LOCATION_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Contract_Location(@ContractID, NULL) END IF (@FullRecalc = 1 OR UPDATE(Department)) BEGIN DELETE FROM LNK_CONTRACT_DEPARTMENT_VIRTUAL WHERE Left_Join = @ContractID INSERT INTO LNK_CONTRACT_DEPARTMENT_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Contract_Department(@ContractID, NULL) END IF (@FullRecalc = 1 OR UPDATE(Contract_Type)) BEGIN DELETE FROM LNK_CONTRACT_CONTRACT_TYPE_VIRTUAL WHERE Left_Join = @ContractID INSERT INTO LNK_CONTRACT_CONTRACT_TYPE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Contract_Contract_Type(@ContractID, NULL) END FETCH NEXT FROM ContractCursor INTO @ContractID END CLOSE ContractCursor DEALLOCATE ContractCursor IF (@PayPayGrade = 1 AND (@FullRecalc = 1 OR UPDATE(Pay_Grade))) BEGIN SET @PayChangeCount = (SELECT COUNT(LPC.Left_Join) FROM LNK_PAY_CONTRACT LPC WITH (NOLOCK) INNER JOIN DT_CONTRACT DTC WITH (NOLOCK) ON LPC.Right_Join = DTC.Entity_Id INNER JOIN (SELECT DISTINCT Entity_Id FROM INSERTED WHERE Entity_Id > 0 UNION SELECT DISTINCT Entity_Id FROM DELETED WHERE Entity_Id > 0) JobChanges ON CAST(DTC.Job as int) = JobChanges.Entity_Id) IF (@PayChangeCount BETWEEN 1 AND (@ChangeThreshold * 10)) BEGIN DECLARE PayCursor CURSOR LOCAL FAST_FORWARD FOR SELECT DISTINCT LPC.Left_Join FROM LNK_PAY_CONTRACT LPC WITH (NOLOCK) INNER JOIN DT_CONTRACT DTC WITH (NOLOCK) ON LPC.Right_Join = DTC.Entity_Id AND CAST(DTC.Job as int) = @CurrentID OPEN PayCursor FETCH NEXT FROM PayCursor INTO @PayID WHILE @@FETCH_STATUS = 0 BEGIN DELETE FROM LNK_PAY_PAY_GRADE_VIRTUAL WHERE Left_Join = @PayID INSERT INTO LNK_PAY_PAY_GRADE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Pay_Pay_Grade(@PayID, NULL) FETCH NEXT FROM PayCursor INTO @PayID END CLOSE PayCursor DEALLOCATE PayCursor END END SET @Processed = @Processed + @CurrentID END FETCH NEXT FROM ChangesCursor INTO @Entity_Id SET @JobLoop = @@FETCH_STATUS END CLOSE ChangesCursor DEALLOCATE ChangesCursor IF (@PayPayGrade = 1 AND (@FullRecalc = 1 OR UPDATE(Pay_Grade))) BEGIN IF (@PayChangeCount > (@ChangeThreshold * 10)) BEGIN DELETE FROM LNK_PAY_PAY_GRADE_VIRTUAL DBCC CHECKIDENT (LNK_PAY_PAY_GRADE_VIRTUAL, RESEED, 1) INSERT INTO LNK_PAY_PAY_GRADE_VIRTUAL(Left_Join, Right_Join, Start_Date, End_Date) SELECT Left_Join, Right_Join, Start_Date, End_Date FROM fn_Pay_Pay_Grade(NULL, NULL) END END END END GO SET QUOTED_IDENTIFIER ON GO