Ich möchte eine gespeicherte Prozedur erstellen, die für jeden Tag in einem bestimmten Datumsbereich eine Zeile in einer Tabelle erstellt. Die gespeicherte Prozedur akzeptiert zwei Eingaben - Ein Startdatum und ein Enddatum des vom Benutzer gewünschten Datumsbereichs.
Nehmen wir also an, ich habe einen Tisch wie diesen:
SELECT Day, Currency
FROM ConversionTable
Tag ist eine DateTime und Währung ist nur eine ganze Zahl.
Nehmen wir zur Vereinfachung an, ich möchte immer, dass die Spalte Währung für jede dieser eingefügten Zeilen 1 ist. Wenn also jemand "5. März 2017" als Startdatum und "11. April 2017" als Enddatum eingibt, möchte ich die folgenden Zeilen erstellen:
2017-03-05 00:00:00, 1
2017-03-06 00:00:00, 1
...
2017-04-11 00:00:00, 1
Was ist der beste Weg, um die gespeicherte Prozedur zu codieren, um dies zu tun? Ich verwende SQL Server 2008 R2 in meiner Testumgebung, aber unsere reale Umgebung verwendet SQL Server 2012, sodass ich meinen Testcomputer aktualisieren kann, wenn 2012 neue Funktionen eingeführt wurden, die diese Aufgabe erleichtern.
MAXRECURSION
lösende Abfrage wurde der Hinweis hinzugefügt .DATEADD(DAY, 1, theDate) < @EndDate
, erhalten Sie das Ende des Bereichs nicht, wenn beide Datums- / Uhrzeitwerte dieselbe Zeitkomponente haben. Ich habe die Antwort entsprechend geändert, aber mit<= @EndDate
. Wenn Sie nicht möchten, dass der Wert für das Ende des Bereichs< @EndDate
trotzdem enthalten ist, ist dies in der Tat korrekt.Eine andere Möglichkeit ist die Verwendung einer Tabellenwertfunktion. Dieser Ansatz ist sehr schnell und bietet etwas mehr Flexibilität. Sie geben den Datums- / Zeitbereich, DatePart und Increment an. Bietet auch den Vorteil, es in eine CROSS APPLY aufzunehmen
Beispielsweise
Kehrt zurück
Die UDF bei Interesse
quelle
Am Beispiel von Aaron Bertrands Beitrag zum Erstellen einer Datumsdimensionstabelle habe ich Folgendes gefunden:
Sie sollten in der Lage sein, diese Art von Logik in Ihre gespeicherte Prozedur einzufügen und alles hinzuzufügen, was Sie sonst noch benötigen.
quelle
Ich musste kürzlich ein ähnliches Problem bei Redshift lösen, bei dem ich nur Lesezugriff hatte und daher eine rein SQL-basierte Lösung (keine gespeicherten Prozeduren) benötigte, um eine Zeile für jede Stunde in einem Datumsbereich als Ausgangspunkt für meine Ergebnismenge zu erhalten. Ich bin sicher, andere können dies eleganter gestalten und für ihre Zwecke modifizieren, aber für Bedürftige ist hier meine gehackte Lösung:
quelle