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ę @MinToAdd
po 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 @MinutesToAdd
minut do @StartTime
i @EndTime
?
Uwaga: używam time
typu danych.
Aktualizacja :
Prawidłowa odpowiedź powinna zawierać następujące informacje:
- Jak dodać minuty do
time
typu 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
time
zmiennej, lub ryzyko przewróceniatime
zmiennej. Jeśli nie ma żadnych problemów, proszę to zaznaczyć.
sql-server
sql-server-2008
Trisped
źródło
źródło
Odpowiedzi:
W nowych typach nie można używać leniwej skróconej arytmetyki. Próbować:
Pamiętaj, że mimo ochrony
@MinutesToAdd
przed przepełnieniem, nie zabezpieczyłeś wyniku przed przepełnieniem. Nie powoduje to błędu, ale może nie być oczekiwanym rezultatem.Wynik:
Zakładam, że to musi przejść przez pewien rodzaj wewnętrznej konwersji, ponieważ nie można uzyskać tego wyniku, mówiąc:
Wynik:
Musisz zastanowić się, jak chcesz obsługiwać obliczenia, które prowadzą do jednego
@EndTime
lub obu,@StartTime
i@EndTime
być na następny dzień.Ponadto - aby spełnić kolejny nowy wymóg w „idealnej odpowiedzi” - nie ma utraty precyzji. Zgodnie z dokumentacją , zwracany typ
DATEADD
jest taki sam jak dane wejściowe:Dlatego wchodzimy
TIME
,TIME
wychodzimy.źródło
DATEADD
zwraca 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.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
źródło