Jak dodać minuty do typu danych czasu?

10

Mam procedurę składowaną, która wstawia dwa rekordy do tabeli, różnica między nimi polega na tym, że kolumna czasowa drugiego rekordu znajduje się @MinToAddpo pierwszym:

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

Jaki jest prawidłowy sposób dodawania @MinutesToAddminut do @StartTimei @EndTime?
Uwaga: używam timetypu danych.

Aktualizacja :
Prawidłowa odpowiedź powinna zawierać następujące informacje:

  • Jak dodać minuty do timetypu danych.
  • Że proponowane rozwiązanie nie powoduje utraty precyzji.
  • Problemy lub obawy, o których należy pamiętać w przypadku, gdy minuty byłyby zbyt duże, aby zmieściły się w timezmiennej, lub ryzyko przewrócenia timezmiennej. Jeśli nie ma żadnych problemów, proszę to zaznaczyć.
Trisped
źródło
5
Nie rozumiem, w jaki sposób twoja edycja pytania wyjaśnia bardziej szczegółowe pytanie.
swasheck
@swasheck Wyraźnie stwierdzam trzy rzeczy, których szukam. Wyznaczam również granice tego, czego nie szukam.
Trisped

Odpowiedzi:

36

W nowych typach nie można używać leniwej skróconej arytmetyki. Próbować:

DATEADD(MINUTE, @MinutesToAdd, @StartTime)

Pamiętaj, że mimo ochrony @MinutesToAddprzed przepełnieniem, nie zabezpieczyłeś wyniku przed przepełnieniem. Nie powoduje to błędu, ale może nie być oczekiwanym rezultatem.

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

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

Wynik:

00:19:00

Zakładam, że to musi przejść przez pewien rodzaj wewnętrznej konwersji, ponieważ nie można uzyskać tego wyniku, mówiąc:

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

Wynik:

Wiadomość 241, poziom 16, stan 1, wiersz 1
Konwersja nie powiodła się podczas konwersji daty i / lub czasu z ciągu znaków.

Musisz zastanowić się, jak chcesz obsługiwać obliczenia, które prowadzą do jednego @EndTimelub obu, @StartTimei @EndTimebyć na następny dzień.

Ponadto - aby spełnić kolejny nowy wymóg w „idealnej odpowiedzi” - nie ma utraty precyzji. Zgodnie z dokumentacją , zwracany typ DATEADDjest taki sam jak dane wejściowe:

Zwracany typ danych to typ danych argumentu daty , z wyjątkiem literałów łańcuchowych.

Dlatego wchodzimy TIME, TIMEwychodzimy.

Aaron Bertrand
źródło
1
+1 @Aaron Alternatywnie możesz przekonwertować StartTime i TimeToAdd na datetime, a następnie dodać. Konwersja TimeToAdd będzie bardzo nieuporządkowana, gdy minuty będą> 59. DATEADD jest najlepszym rozwiązaniem.
brian
Jeśli dodasz, że DATEADDzwraca ten sam typ co argument daty, wtedy zaakceptuję. „W razie potrzeby zapobiec przepełnieniu?” linia nie jest potrzebna. Problem z przejściem będzie obsługiwany przez źródło danych i miejsce docelowe danych.
Trisped 10.01.2013
3
@ Pewnie, jeśli dodasz do pytania, że ​​nie uważasz, że DATEADD jest odpowiednie, ponieważ myślałeś, że może zwrócić tylko DATETIME i że może to powodować problemy. W przeciwnym razie nie wydaje się mieć znaczenia dla twojego pytania lub dla przyszłych czytelników ...
Aaron Bertrand
W jaki sposób „Sugeruję, że używam typu danych czasu” nie sugeruje tego znaczenia. Poza tym, dlaczego zmieniłeś moje pytanie, aby niestosownie używać wiersza zamiast zapisu?
Trisped 10.01.2013
1
@Przesłano, że edycja używa lepszej terminologii i zapoznaj się z często zadawanymi pytaniami na temat edycji - nie ma już więcej tam iz powrotem, albo zablokuję pytanie. Aaron ma rację, że musimy wyjaśnić wszystko innym, masz swoją odpowiedź. Proszę rozważyć edycję pytania zgodnie z sugestiami, które według niego byłyby pomocne: Aaron uprzejmie zaoferował dodanie informacji, na które chcesz odpowiedzieć, jeśli to zrobisz.
Jack mówi, że spróbuj topanswers.xyz
0

Wystarczy użyć funkcji dateadd, aby dodać minuty w liczbach całkowitych do „0:00”. Następnie wróć do czasu.

Wybierz obsadę (dateadd (minuta, 84, „0: 00”) jako czas)

Tutaj 84 jest liczbą całkowitą, którą chcę wyrazić jako „czas”.

Dodałem to do „0:00”, a następnie, aby usunąć składnik daty, rzutowałem go na typ godziny. Nie jest wymagane niestandardowe kodowanie.

(Bez nazwy kolumny)

01: 24: 00.0000000

Jun Sato
źródło