Wie füge ich einem Zeitdatentyp Minuten hinzu?

10

Ich habe eine gespeicherte Prozedur, die zwei Datensätze in eine Tabelle einfügt. Der Unterschied zwischen den Datensätzen besteht darin, dass die Zeitspalte des zweiten Datensatzes @MinToAddnach dem ersten steht:

CREATE PROCEDURE CreateEntry
    /*Other columns*/
    @StartTime time(2),
    @EndTime time(2),
    @MinutesToAdd smallint
    AS
BEGIN
    SET NOCOUNT ON;

    SET @MinutesToAdd = @MinutesToAdd % 1440;   --Prevent overflow if needed?
    IF (@MinutesToAdd > 0)
    BEGIN
    INSERT INTO ClientNotification (/*Other columns*/ startTime, endTime)
        OUTPUT inserted.id
        VALUES
               (/*Other columns*/ @StartTime, @EndTime),
               (/*Other columns*/ @StartTime + @MinutesToAdd, @EndTime + @MinutesToAdd);
    END
    ELSE
    BEGIN
        /*Whatever ELSE does.*/
    END
END

Was ist der richtige Weg, um @MinutesToAddMinuten zu @StartTimeund hinzuzufügen @EndTime?
Bitte beachten Sie, dass ich den timeDatentyp verwende.

Update :
Eine korrekte Antwort sollte folgende Informationen enthalten:

  • So fügen Sie einem timeDatentyp Minuten hinzu .
  • Dass die vorgeschlagene Lösung nicht zu einem Genauigkeitsverlust führt.
  • Probleme oder Bedenken, die zu beachten sind, falls das Protokoll zu groß wäre, um in eine timeVariable zu passen , oder das Risiko eines Rollover der timeVariablen. Wenn es keine Probleme gibt, geben Sie dies bitte an.
Trisped
quelle
5
Ich sehe nicht, wie Ihre Bearbeitung Ihrer Frage die vorliegende Frage weiter verdeutlicht.
Swasheck
@swasheck Ich gebe ausdrücklich die drei Dinge an, die ich suche. Ich setze auch Grenzen für das, wonach ich nicht suche.
Trisped

Antworten:

36

Sie können mit den neuen Typen keine faulen Kurzschriftarithmetik verwenden. Versuchen:

DATEADD(MINUTE, @MinutesToAdd, @StartTime)

Beachten Sie, dass Sie @MinutesToAdddas Ergebnis nicht vor Überlauf geschützt haben, obwohl Sie es vor Überlauf geschützt haben. Dies führt jedoch nicht zu einem Fehler, sondern ist möglicherweise nicht das erwartete Ergebnis.

DECLARE @StartTime TIME(0) = '23:59';
DECLARE @MinutesToAdd INT = 20;

SELECT DATEADD(MINUTE, @MinutesToAdd, @StartTime);

Ergebnis:

00:19:00

Ich gehe davon aus, dass dies eine Art interne Konvertierung durchlaufen muss, da Sie dieses Ergebnis nicht erzielen können, wenn Sie sagen:

DECLARE @StartTime TIME(0) = '24:19';

Ergebnis:

Meldung 241, Ebene 16, Status 1, Zeile 1 Die
Konvertierung ist fehlgeschlagen, wenn Datum und / oder Uhrzeit aus der Zeichenfolge konvertiert wurden.

Sie müssen überlegen, wie Sie mit Berechnungen umgehen möchten, die zu einem @EndTimeoder beiden führen, @StartTimeund @EndTimeam nächsten Tag sein.

Um eine weitere neue Anforderung in Ihrer "idealen Antwort" zu erfüllen, gibt es keinen Präzisionsverlust. Gemäß der Dokumentation entspricht der Rückgabetyp von DATEADDder Eingabe:

Der Rückgabedatentyp ist der Datentyp des Datums Argument, mit Ausnahme von Zeichenketten.

Deshalb rein TIME, TIMEraus.

Aaron Bertrand
quelle
1
+1 @Aaron Alternativ können Sie StartTime und TimeToAdd in datetime konvertieren und dann hinzufügen. Das Konvertieren von TimeToAdd ist sehr unübersichtlich, wenn die Minuten> 59 sind. DATEADD ist die beste Lösung.
Brian
Wenn Sie hinzufügen, dass DATEADDderselbe Typ wie das Datumsargument zurückgegeben wird, werde ich akzeptieren. Die Option "Überlauf bei Bedarf verhindern?" Leitung wird nicht benötigt. Das Rollover-Problem wird von der Datenquelle und dem Ziel der Daten behandelt.
Trisped
3
@Trisped sicher, wenn Sie der Frage hinzufügen, dass Sie DATEADD nicht für angemessen hielten, weil Sie dachten, es könnte nur DATETIME zurückgeben und dass dies Probleme verursachen könnte. Andernfalls scheint es für Ihre Frage oder für zukünftige Leser nicht relevant zu sein ...
Aaron Bertrand
Wie wird die Relevanz nicht durch "Bitte beachten Sie, dass ich den Zeitdatentyp verwende" impliziert? Warum haben Sie meine Frage dahingehend geändert, dass Zeile anstelle von Aufzeichnung unbeständig verwendet wird?
Trisped
1
@Trisped die Bearbeitung verwendet eine bessere Terminologie und bitte lesen Sie die FAQ zur Bearbeitung - Lets haben kein Hin und Her mehr oder ich werde die Frage sperren. Aaron hat recht, dass wir alles für andere klar machen müssen, Sie haben Ihre Antwort. Bitte überlegen Sie, Ihre Frage so zu bearbeiten, wie er es vorschlägt, wenn Sie dies für hilfreich halten: Aaron hat freundlicherweise angeboten, die gewünschten Informationen zu seiner Antwort hinzuzufügen, wenn Sie dies tun.
Jack sagt, versuchen Sie topanswers.xyz
0

Verwenden Sie einfach die Funktion dateadd, um Ihre Minuten in Ganzzahl gegen '0:00' zu addieren. Dann zurück in die Zeit werfen.

Wählen Sie Besetzung (Datum (Minute, 84, '0: 00') als Zeit).

Hier ist 84 die ganzzahlige Minute, die ich als "Zeit" -Typ ausdrücken möchte.

Ich habe das zu '0:00' hinzugefügt und dann, um die Datumskomponente zu entfernen, in den Zeittyp umgewandelt. Keine benutzerdefinierte Codierung erforderlich.

(Kein Spaltenname)

01: 24: 00.0000000

Jun Sato
quelle