Mám uloženou proceduru, která vloží dva záznamy do tabulky, rozdíl mezi záznamy je v tom, že časový sloupec druhého záznamu je @MinToAdd
za první:
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
Jaký je správný způsob přidání @MinutesToAdd
minut do @StartTime
a @EndTime
?
Upozorňujeme, že používám datový typ time
.
Aktualizace:
Správná odpověď by měla obsahovat následující informace:
time
.time
, nebo by mohlo dojít k převrácení proměnné time
. Pokud neexistují žádné problémy, uveďte to prosím.U nových typů nemůžete použít lenivou zkratkovou aritmetiku. Snaž se:
DATEADD(MINUTE, @MinutesToAdd, @StartTime)
Všimněte si, že i když jste chránili své @MinutesToAdd
před přetečením, nechránili jste výsledek před přetečením. To nevytváří chybu, ale nemusí to být výsledek, který očekáváte.
DECLARE @StartTime TIME(0) = '23:59';
DECLARE @MinutesToAdd INT = 20;
SELECT DATEADD(MINUTE, @MinutesToAdd, @StartTime);
Výsledek:
00:19:00
Předpokládám, že to musí projít nějakým druhem interní konverze, protože tento výsledek jste nemohli dosáhnout slovy:
DECLARE @StartTime TIME(0) = '24:19';
Výsledek:
Msg 241, úroveň 16, stav 1, řádek 1
Převod selhal při převodu data a/nebo času z řetězce znaků.
Musíte zvážit, jak chcete zpracovat výpočty, které vedou buď k @EndTime
nebo oboje @StartTime
a @EndTime
být příští den.
Také - k vyřešení dalšího nového požadavku ve vaší „ideální odpovědi“ - nedochází ke ztrátě přesnosti. Podle dokumentace je návratový typ DATEADD
stejný jako vstup:
Návratový datový typ je datový typ argumentu date , s výjimkou řetězcových literálů.
Proto TIME
in, TIME
out.
Jednoduše použijte funkci dateadd a přidejte minuty do celého čísla proti '0:00'. Pak vrhněte zpět na čas.
Vyberte cast (dateadd (minuta, 84, '0: 00') jako čas)
Zde je 84 celé číslo, které chci vyjádřit typem "time".
Přidal jsem to do '0:00' a pak abych odstranil komponentu data, vložím ji do typu času. Není třeba žádné vlastní kódování.
01: 24: 00.0000000