Come faccio ad aggiungere minuti a un tipo di dati temporali?


10

Ho una procedura memorizzata che inserisce due record in una tabella, la differenza tra i record è che la colonna temporale del secondo record è @MinToAddsuccessiva al primo:

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

Qual è il modo corretto di aggiungere @MinutesToAddminuti a @StartTimee @EndTime?
Nota che sto usando il timetipo di dati.

Aggiornamento :
una risposta corretta dovrebbe contenere le seguenti informazioni:

  • Come aggiungere minuti a un timetipo di dati.
  • Che la soluzione proposta non si traduca in una perdita di precisione.
  • Problemi o preoccupazioni di cui tenere conto nel caso in cui i minuti fossero troppo grandi per adattarsi a una timevariabile, o rischio di ribaltamento della timevariabile. Se non ci sono problemi, si prega di dichiararlo.

5
Non vedo come la tua modifica alla tua domanda chiarisca ulteriormente la domanda a portata di mano.
Scorri l'

@swasheck Dichiaro esplicitamente le tre cose che sto cercando. Ho anche fissato limiti a ciò che non sto cercando.
Trisped

Risposte:


36

Non puoi usare l'aritmetica abbreviata pigra con i nuovi tipi. Provare:

DATEADD(MINUTE, @MinutesToAdd, @StartTime)

Nota che anche se hai protetto il tuo @MinutesToAddoverflow, non hai protetto il risultato da overflow. Questo non produce un errore, tuttavia, potrebbe non essere il risultato che ti aspetti.

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

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

Risultato:

00:19:00

Presumo che questo debba passare attraverso un qualche tipo di conversione interna, perché non è stato possibile ottenere quel risultato dicendo:

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

Risultato:

Messaggio 241, livello 16, stato 1,
conversione riga 1 non riuscito durante la conversione di data e / o ora dalla stringa di caratteri.

È necessario considerare come si desidera gestire i calcoli che portano a uno @EndTimeo entrambi @StartTimee @EndTimedi essere il giorno successivo.

Inoltre, per rispondere a un altro nuovo requisito nella tua "risposta ideale", non c'è perdita di precisione. Come da documentazione , il tipo di restituzione di DATEADDè lo stesso dell'input:

Il tipo di dati restituito è il tipo di dati dell'argomento date , ad eccezione dei valori letterali di stringa.

Pertanto, TIMEdentro, TIMEfuori.


1
+1 @Aaron In alternativa puoi convertire StartTime e TimeToAdd in datetime e quindi aggiungere. La conversione di TimeToAdd sarà molto complicata quando i minuti sono> 59. DATEADD è la soluzione migliore.
Brian

Se aggiungi che DATEADDrestituisce lo stesso tipo dell'argomento data, accetterò. Il "Prevenire overflow se necessario?" la linea non è necessaria. Il problema del roll over verrà gestito dalla fonte dei dati e dalla destinazione dei dati.
Trisped il

3
@Trisped certo, se aggiungi alla domanda che non pensavi che DATEADD fosse appropriato perché pensavi che potesse solo restituire DATETIME e che ciò potesse causare problemi. Altrimenti non sembra rilevante per la tua domanda o per i futuri lettori ...
Aaron Bertrand

In che modo la pertinenza non è implicita nel "Si noti che sto usando il tipo di dati temporali". Inoltre, perché hai cambiato la mia domanda per utilizzare in modo incostante file anziché record?
Trisped il

1
@Trisped la modifica utilizza una terminologia migliore e si prega di vedere le domande frequenti sulla modifica —let non hanno più avanti e indietro o bloccherò la domanda. Aaron ha ragione sul fatto che dobbiamo chiarire tutto per gli altri, hai la tua risposta. Ti preghiamo di considerare di modificare la tua domanda seguendo le linee che suggerisce se ritieni che sarebbe utile: Aaron si è gentilmente offerto di aggiungere le informazioni che vuoi alla sua risposta se lo fai.
Jack dice di provare topanswers.xyz l'

0

Usa semplicemente la funzione dateadd per aggiungere i tuoi minuti in numero intero a "0:00". Quindi tornare indietro nel tempo.

Seleziona cast (dateadd (minuto, 84, '0: 00') come ora)

Qui, 84 è il minuto intero che voglio essere espresso nel tipo "tempo".

L'ho aggiunto a '0:00' e quindi per rimuovere il componente data, lo lancio al tipo di ora. Nessuna codifica personalizzata necessaria.

(Nessun nome di colonna)

01: 24: 00,0000000

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.