2009-04-29 8 views
0

Ich habe an einer Stored Procedure gearbeitet, die die Zeit überprüft und dann Datensätze zurück in den letzten vollen 24 Stunden zwischen 8am und den vorherigen 8am abrufen. Nehmen Sie zum Beispiel an, dass es derzeit 10 Uhr morgens ist. Die gespeicherte Prozedur zeigt die aktuelle Uhrzeit an, stellt fest, dass es nach 8 Uhr morgens ist, und legt die Abfrage so fest, dass sie 24 Stunden von 8 Uhr morgens bis 8 Uhr gestern rückwärts läuft. Wenn es, sagen wir, 7 Uhr morgens wäre, würde die Abfrage eingestellt werden, um von 8 Uhr gestern bis 8 Uhr am Vortag zu überprüfen. Das war eigentlich relativ einfach zu machen. Der SP soll zum Abrufen von Datensätzen für einen Bericht verwendet werden, der Aufträge in der angegebenen Zeitspanne verfolgt.Wählen Sie eine Variable TimeSpan mit einem beliebigen Endpunkt aus

Sie haben mich jedoch zurückgerufen und mich gebeten, die gespeicherte Prozedur so zu ändern, dass die Stunde, zu der der Bericht endet, und die überprüfte Zeitspanne vom Front-End der Site aus konfigurierbar ist. Ich habe das funktioniert für TimeSpans größer oder gleich 24 Stunden, aber habe Probleme mit Spannen darunter. Hier ist, was ich bisher für meine Logik in der gespeicherten Prozedur haben -

-- 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 und @TimeSpan sind alle Parameter bereit, die von dem Bericht Front-End festgelegt werden, und standardmäßig auf ‚08‘, "AM" und 24 jeweils. Ich weiß, dass die Einstellung des Tagesbereichs im ELSE-Teil der obersten Ebene ordnungsgemäß funktioniert. Ich bin ziemlich sicher, dass das Problem mit der Einstellung des Stunden-Offsets darin liegt, wie ich die DATEADD- und DATEDIFF-Funktion hier benutze, aber ich konnte nicht herausfinden, wo ich gerade meinen Miss-Schritt mache. Jede Hilfe hier würde sehr geschätzt werden.

Antwort

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, das funktioniert großartig, sobald ich die Stunde in eine Ganzzahl anstelle von Nvarchar geändert habe. Vielen Dank, die Hilfe wird sehr geschätzt! – Clyde

+0

Ich muss korrigiert stehen - es ist viel weniger komplex als die verschachtelte wenn Struktur, so ist bereits eine große Verbesserung, aber es hat immer noch das gleiche Problem. Der kürzeste Zeitraum, für den er ausgewählt wird, beträgt 24 Stunden. Wenn es unter 24 Stunden ist, egal was ich anfordere, kommt es immer noch mit diesem 1-Tage-Fenster. – Clyde

+0

@Clyde, Mein Code funktioniert korrekt, wie beschrieben (Sie können "SELECT @DateStart, @DateEnd" tun, um dies zu überprüfen). Ich vermute, dass das Problem anderswo in Ihrem Code ist, wahrscheinlich in der Abfrage, in der Sie tatsächlich das berechnete Anfangs- und Enddatum verwenden. Können Sie diese Abfrage posten? – LukeH

0

Warum nicht einfach eine Abfrage wie verwenden:

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

Wenn Sie über die Zeit betroffen sind korrekt zu sein (dh die Daten müssen so sein '01/01/1900 13.00.00' oder etwas) Geben Sie einfach das Datum selbst ein und fügen Sie die Zeit als Funktion in SQL hinzu.

Wenn dies nicht das ist, was Sie beabsichtigen, fügen Sie bitte mehr SQL hinzu, damit wir besser verstehen, was Sie erreichen möchten.

+0

Das ist tatsächlich, was die select-Anweisung, die dem obigen folgt, beträgt. Die select-Anweisung ist einfach. Das Problem besteht darin, das richtige Datum korrekt zu berechnen, um den Bereich zu bestimmen. Die Auswahl eines Zeitraums in Tagen ist einfach und der Code funktioniert bereits in diesem Sinne. Sie möchten jedoch, dass derselbe Bericht eine Reihe von Stunden auswählen kann, und genau hier liegt das Problem. Ob im VB-Backend oder SQL Server, irgendwann muss ich den genauen Zeitbereich berechnen, der ausgewählt wird. – Clyde

Verwandte Themen