J’ai une question sur ma requête Je souhaite générer une liste de dates de planification pour une tâche sql à partir de sa fréquence pour obtenir les dates d’exécution mais le problème est que ma requête ne fonctionne pas.

freq_type int Fréquence d’exécution d’une tâche pour cette planification.

Fréquence = 8 (hebdomadaire) freq_interval est un ou plusieurs des éléments suivants :

1 = Dimanche

2 = Lundi

4 = Mardi

8 = Mercredi

16 = Jeudi

32 = Vendredi

64 = Samedi

pouvez-vous s’il vous plaît m’aider à générer ma liste de dates, sur la fréquence hebdomadaire il y a des emplois qui fonctionnent du lundi au samedi, ou lundi, mardi ou lundi mardi mercredi, etc. et fréquence mensuelle




Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
DECLARE @DateDebut1 DATETIME
SET @DateDebut1 = '2023-01-01'
 
DECLARE @DateFin DATETIME
SET @DateFin = GETDATE()
 
 
CREATE TABLE #DatesExecutionTemp (
    NomJob VARCHAR(255),
    NomPlanification VARCHAR(255),
    DateExecution DATETIME,
    Frequence VARCHAR(100)
);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
-- Requête principale avec le calcul de la fréquence hebdomadaire
INSERT INTO #DatesExecutionTemp (NomJob, NomPlanification, DateExecution, Frequence)
SELECT
    j.name AS NomJob,
    s.name AS NomPlanification,
    TRY_CONVERT(DATETIME, CONVERT(VARCHAR(8), s.active_start_date, 112) + ' ' +
            STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), s.active_start_time), 6), 3, 0, ':'), 6, 0, ':')) AS DateExecution,
    CASE
        WHEN s.freq_type = 1 THEN 'Une seule fois'
        WHEN s.freq_type = 4 THEN 'Quotidienne'
        WHEN s.freq_type = 8 THEN 'Hebdomadaire'
        WHEN s.freq_type = 16 THEN 'Mensuelle'
        WHEN s.freq_type = 32 THEN 'Mensuelle relative'
    END AS Frequence
FROM
    sysschedules s
JOIN sysjobschedules js ON js.schedule_id = s.schedule_id
LEFT JOIN sysjobs j ON j.job_id = js.job_id
WHERE
    TRY_CONVERT(DATETIME, CONVERT(VARCHAR(8), s.active_start_date, 112) + ' ' +
            STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), s.active_start_time), 6), 3, 0, ':'), 6, 0, ':')) <= @DateFin
    AND s.enabled = 1
 
ORDER BY j.name ASC, DateExecution DESC
 
-- Boucle WHILE pour générer les dates d'exécution suivantes en fonction de la fréquence
DECLARE @NomJob VARCHAR(255)
DECLARE @NomPlanification VARCHAR(255)
DECLARE @DateExecution DATETIME
DECLARE @Frequence VARCHAR(100)
 
DECLARE @FreqInterval INT
SELECT @FreqInterval = s.freq_interval
FROM sysschedules s
JOIN sysjobschedules js ON js.schedule_id = s.schedule_id
JOIN sysjobs j ON j.job_id = js.job_id          
 
DECLARE @BinaryString VARCHAR(MAX)
SET @BinaryString = ''
 
WHILE @FreqInterval > 0
BEGIN
    SET @BinaryString = CAST((@FreqInterval % 2) AS VARCHAR) + @BinaryString
    SET @FreqInterval = @FreqInterval / 2
END
 
DECLARE @DayOffset INT
SET @DayOffset = 0
 
DECLARE curPlanifications CURSOR FOR
SELECT NomJob, NomPlanification, DateExecution, Frequence
FROM #DatesExecutionTemp
 
OPEN curPlanifications
FETCH NEXT FROM curPlanifications INTO @NomJob, @NomPlanification, @DateExecution, @Frequence
 
WHILE @@FETCH_STATUS = 0
BEGIN
    -- ajout de la date d'exécution initiale dans la table temporaire
    INSERT INTO #DatesExecutionTemp (NomJob, NomPlanification, DateExecution, Frequence)
    VALUES (@NomJob, @NomPlanification, @DateExecution, @Frequence)
 
    WHILE @DateExecution <= @DateFin
    BEGIN
        -- Ajoutez ici la boucle IF avec les conditions de fréquence et le calcul des dates d'exécution suivantes
        IF @Frequence = 'Quotidienne'
        BEGIN
            SET @DateExecution = DATEADD(DAY, 1, @DateExecution)
        END
        ELSE IF @Frequence = 'Hebdomadaire'
        BEGIN
            -- Itère sur chaque bit de la chaîne binaire pour calculer les dates
            WHILE @DayOffset < 7
            BEGIN
                IF SUBSTRING(@BinaryString, @DayOffset + 1, 1) = '1' -- si dans le code binaire on a 1 alors 
                BEGIN
                    -- Ajoute l'offset du jour à la date d'exécution
                    SET @DateExecution = DATEADD(DAY, @DayOffset, @DateExecution)
 
                    -- Ajoute une semaine si la date d'exécution est inférieure à la date actuelle
                    IF @DateExecution < GETDATE()
                    BEGIN
                        SET @DateExecution = DATEADD(WEEK, 1, @DateExecution)
                    END 
 
                    -- Sort de la boucle si la date d'exécution est supérieure à la date actuelle
                    IF @DateExecution > GETDATE()
                    BEGIN
                        BREAK
                    END 
                END
 
                SET @DayOffset = @DayOffset + 1
            END
        END
        ELSE IF @Frequence = 'Mensuelle' 
        BEGIN
            SET @DateExecution = DATEADD(MONTH, 1, @DateExecution)
        END
 
            -- Ajoute la date d'exécution générée dans la table temporaire
            INSERT INTO #DatesExecutionTemp (NomJob, NomPlanification, DateExecution, Frequence)
            VALUES (@NomJob, @NomPlanification, @DateExecution, @Frequence)
 
    END
 
    FETCH NEXT FROM curPlanifications INTO @NomJob, @NomPlanification, @DateExecution, @Frequence
END
 
CLOSE curPlanifications
DEALLOCATE curPlanifications
 
-- Sélection finale des dates d'exécution
SELECT NomJob, NomPlanification, DateExecution, Frequence
FROM #DatesExecutionTemp
WHERE DateExecution BETWEEN @DateDebut1 AND @DateFin
ORDER BY NomJob ASC, DateExecution DESC
 
-- Suppression de la table temporaire
DROP TABLE #DatesExecutionTemp
.sqlsql-serveurPostgreSQL