web-dev-qa-db-fra.com

Comment ajouter des minutes à un type de données de temps?

J'ai une procédure stockée qui insère deux enregistrements dans une table, la différence entre les enregistrements est que la colonne de temps du deuxième enregistrement est @MinToAdd après le premier:

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

Quelle est la bonne façon d'ajouter @MinutesToAdd minutes à @StartTime et @EndTime?
Veuillez noter que j'utilise le type de données time.

Mise à jour:
Une bonne réponse doit contenir les informations suivantes:

  • Comment ajouter des minutes à un type de données time.
  • Que la solution proposée n'entraîne pas une perte de précision.
  • Problèmes ou préoccupations à prendre en compte dans le cas où les minutes seraient trop grandes pour tenir dans une variable time, ou risque de basculer la variable time. S'il n'y a aucun problème, veuillez l'indiquer.
10
Trisped

Vous ne pouvez pas utiliser l'arithmétique raccourcie paresseuse avec les nouveaux types. Essayer:

DATEADD(MINUTE, @MinutesToAdd, @StartTime)

Notez que même si vous avez protégé votre @MinutesToAdd du débordement, vous n'avez pas protégé le résultat du débordement. Cela ne donne pas d'erreur, cependant, ce n'est peut-être pas le résultat que vous attendez.

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

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

Résultat:

00:19:00

Je suppose que cela doit passer par un certain type de conversion interne, car vous ne pouvez pas obtenir ce résultat en disant:

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

Résultat:

Msg 241, niveau 16, état 1, ligne 1
La conversion a échoué lors de la conversion de la date et/ou de l'heure à partir d'une chaîne de caractères.

Vous devez considérer comment vous souhaitez gérer les calculs qui conduisent à @EndTime ou les deux @StartTime et @EndTime pour le lendemain.

Aussi - pour répondre à une autre nouvelle exigence dans votre "réponse idéale" - il n'y a aucune perte de précision. Selon la documentation , le type de retour de DATEADD est le même que l'entrée:

Le type de données de retour est le type de données de l'argument date , à l'exception des littéraux de chaîne.

Par conséquent, TIME in, TIME out.

36
Aaron Bertrand

Utilisez simplement la fonction dateadd pour ajouter vos minutes en entier contre '0:00'. Puis remonte dans le temps.

Sélectionner le casting (dateadd (minute, 84, '0: 00') comme heure)

Ici, 84 est la minute entière que je veux exprimer en type "temps".

J'ai ajouté cela à '0:00', puis pour supprimer le composant date, je l'ai casté en type d'heure. Aucun codage personnalisé n'est nécessaire.

(Pas de nom de colonne)

01: 24: 00.0000000

0
Jun Sato