CREATE OR ALTER PROCEDURE [dbo].[Mm_S_MaintenanceInstructionSchedule] AS BEGIN SET NOCOUNT ON; -- Zamanlanmış iş (Maintenance Instruction Schedule, her gece 01:00). Aktif bakım talimatlarının -- sonraki bakım tarihini Başlangıç Tarihi + k × periyot dizisinde bugüne eşit ya da bugünden sonraki -- ilk tarihe taşır; Bitiş Tarihi geçmişse ya da talimat pasifse tarih boşalır. İş emri tablosu -- geldiğinde vadesi gelen ve onaylanmış talimattan iş emri bu yordamda açılır. -- İş host ve her kiracı için çağrılır, yordam parametre almaz; bütün kiracıların satırlarını işler -- ve aynı gün tekrar çalışması sonucu değiştirmez. DECLARE @Today date = CAST(GETDATE() AS date); UPDATE i SET NextDueDate = CASE WHEN n.NextDate > i.EndDate THEN NULL ELSE n.NextDate END FROM Mm_T_MaintenanceInstruction i CROSS APPLY ( SELECT CASE WHEN i.PeriodUnit IN ('Month', 'Year') THEN 1 ELSE 0 END AS IsMonth, CASE i.PeriodUnit WHEN 'Week' THEN 7 * i.PeriodValue WHEN 'Year' THEN 12 * i.PeriodValue ELSE i.PeriodValue END AS Step ) s CROSS APPLY ( SELECT CASE WHEN s.IsMonth = 1 THEN DATEDIFF(month, i.StartDate, @Today) ELSE DATEDIFF(day, i.StartDate, @Today) END / s.Step AS K ) k CROSS APPLY ( SELECT CASE WHEN s.IsMonth = 1 THEN DATEADD(month, k.K * s.Step, i.StartDate) ELSE DATEADD(day, k.K * s.Step, i.StartDate) END AS Candidate ) c CROSS APPLY ( SELECT CASE WHEN i.StartDate >= @Today THEN i.StartDate WHEN c.Candidate >= @Today THEN c.Candidate WHEN s.IsMonth = 1 THEN DATEADD(month, (k.K + 1) * s.Step, i.StartDate) ELSE DATEADD(day, (k.K + 1) * s.Step, i.StartDate) END AS NextDate ) n WHERE i.IsDeleted = 0 AND i.IsActive = 1 AND i.PeriodValue > 0; UPDATE Mm_T_MaintenanceInstruction SET NextDueDate = NULL WHERE NextDueDate IS NOT NULL AND (IsDeleted = 1 OR IsActive = 0 OR PeriodValue <= 0); END GO