2009-04-29 6 views
0

J'ai travaillé sur une procédure stockée qui vérifie l'heure, puis récupère les enregistrements remontant au cours de la dernière période complète de 24 heures entre 8h et 8h du matin. Ainsi, par exemple, supposons qu'il est actuellement 10h. La procédure stockée regarde l'heure actuelle, note qu'il est plus de 8h du matin, et définit la requête pour qu'elle fonctionne en arrière 24 heures, de 8h aujourd'hui à 8h hier. Si c'était, disons, 7h du matin, la requête serait réglée pour vérifier de 8h hier à 8h du matin la veille. C'était en fait relativement simple à faire. Le SP est destiné à être utilisé pour récupérer des enregistrements pour un rapport de suivi des travaux achevés dans le laps de temps donné.Sélection d'un TimeSpan variable avec un point final arbitraire

Cependant, ils sont revenus sur moi et m'ont demandé de changer la procédure stockée de telle sorte que l'heure à laquelle le rapport se termine, et l'intervalle de temps vérifié, est configurable depuis l'interface du site. J'ai ce travail pour TimeSpans supérieur ou égal à 24 heures, mais j'ai des problèmes avec les travées en dessous. Voici ce que j'ai jusqu'à présent pour ma logique dans la procédure stockée -

-- Retrieves data on jobs that completed/completed with errors during a given time span. 
DECLARE @Hour NVARCHAR(2) 
DECLARE @TimeFrame NVARCHAR(2) 
DECLARE @TimeSpan INTEGER 

SET @TimeSpan = 24 
SET @TimeFrame = 'AM' 
SET @Hour = '08' 

DECLARE @dateStart DateTime 
DECLARE @dateEnd DateTime 

IF @TimeSpan < 24 -- Our TimeSpan is under one full day. 
    BEGIN 
      IF GETDATE() > DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE())) + (@Hour + ':00:00 ' + @TimeFrame) 
      BEGIN 
       SET @dateStart = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - (1 + @TimeSpan))) + (@Hour + ':00:00 ' + @TimeFrame) 
       SET @dateEnd = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE())) + (@Hour + ':00:00 ' + @TimeFrame) 
      END 
     ELSE 
      BEGIN 
       SET @dateStart = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - (2 + @TimeSpan))) + (@Hour + ':00:00 ' + @TimeFrame) 
       SET @dateEnd = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - 1)) + (@Hour + ':00:00 ' + @TimeFrame) 
      END 
    END 
ELSE -- Our TimeSpan is at least one full day. 
    BEGIN 
     IF GETDATE() > DATEADD(D, 0, DATEDIFF(D, 0, GETDATE())) + (@Hour + ':00:00 ' + @TimeFrame) 
      BEGIN 
       SET @dateStart = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - (1 + (@TimeSpan/24)))) + (@Hour + ':00:00 ' + @TimeFrame) 
       SET @dateEnd = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE())) + (@Hour + ':00:00 ' + @TimeFrame) 
      END 
     ELSE 
      BEGIN 
       SET @dateStart = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - (2 + (@TimeSpan/24)))) + (@Hour + ':00:00 ' + @TimeFrame) 
       SET @dateEnd = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - 1)) + (@Hour + ':00:00 ' + @TimeFrame) 
      END 
    END 

@Hour, @TimeFrame et @TimeSpan sont tous les paramètres prêts à être fixé par l'extrémité avant du rapport, et par défaut à « 08 », 'AM' et 24 respectivement. Je sais que le réglage de la plage de jour fonctionne correctement dans la partie ELSE du niveau supérieur si. Je suis raisonnablement certain que le problème avec le décalage d'heure réside dans la façon dont j'utilise la fonction DATEADD et DATEDIFF ici, mais je n'ai pas été capable de comprendre exactement où je fais mon pas manqué. Toute aide est grandement appréciée ici.

Répondre

0
-- convert the required end hour to 24 hour format 
DECLARE @EndHour INT 
SET @EndHour = CASE WHEN @TimeFrame = 'AM' THEN @Hour ELSE @Hour + 12 END 

-- set @DateEnd to the date-only portion of the current datetime 
-- ie, the time portion will be set to 00:00:00 
SET @DateEnd = DATEADD(day, 0, DATEDIFF(day, 0, GETDATE())) 

-- add the required end hour 
SET @DateEnd = DATEADD(hour, @EndHour, @DateEnd) 

-- if @DateEnd is in the future then subtract 24 hours from it 
IF @DateEnd > GETDATE() 
    SET @DateEnd = DATEADD(hour, -24, @DateEnd) 

-- set @DateStart by subtracting the required timespan from @DateEnd 
SET @DateStart = DATEADD(hour, [email protected], @DateEnd) 
+0

Ah, ça marche très bien, une fois que j'ai changé l'heure en un entier au lieu du nvarchar. Merci beaucoup, l'aide est grandement appréciée! – Clyde

+0

Je dois me tenir corrigé - c'est beaucoup moins complexe que la structure imbriquée, donc c'est déjà une grande amélioration, mais le problème est toujours le même. La période la plus courte entre 24 heures est sélectionnée. Si c'est moins de 24 heures, indépendamment de ce que je demande, ça arrive toujours avec cette fenêtre d'une journée. – Clyde

+0

@Clyde, Mon code fonctionne correctement, comme décrit (vous pouvez faire "SELECT @DateStart, @DateEnd" pour vérifier cela). Je suppose que le problème est ailleurs dans votre code, probablement dans la requête où vous utilisez réellement les dates de début et de fin calculées. Pouvez-vous publier cette requête? – LukeH

0

Pourquoi ne pas simplement utiliser une requête comme:

SELECT something 
FROM aTable 
WHERE timeCompleted BETWEEN @StartDate AND @EndDate 

Si vous êtes préoccupé par le moment correct (les dates doivent être '01/01/1900 13:00:00' ou quelque chose comme ça) il suffit de passer la date par lui-même et d'ajouter l'heure en tant que fonction dans le SQL.

Si ce n'est pas ce que vous avez l'intention d'inclure s'il vous plaît inclure plus de SQL afin que nous ayons une meilleure compréhension de ce que vous essayez d'accomplir.

+0

Voilà en quoi consiste l'instruction select qui suit ce qui précède. L'instruction select est simple. Le problème est de calculer correctement la date correcte pour déterminer la plage par rapport. La sélection d'une plage en jours est facile, et le code fonctionne déjà à cet effet. Cependant, ils veulent que le même rapport puisse sélectionner une gamme de quelques heures, et c'est là que réside le problème. Que ce soit dans le backend VB ou SQL Server, je dois calculer la plage horaire sélectionnée. – Clyde

Questions connexes