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

10

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 @MinToAddaprè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 des @MinutesToAddminutes à @StartTimeet @EndTime?
Veuillez noter que j'utilise le timetype de données.

Mise à jour :
une réponse correcte doit contenir les informations suivantes:

  • Comment ajouter des minutes à un timetype de données.
  • 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 longues pour tenir dans une timevariable, ou risque de reconduire la timevariable. S'il n'y a aucun problème, veuillez l'indiquer.
Trisped
la source
5
Je ne vois pas comment votre modification de votre question clarifie davantage la question à portée de main.
swasheck
@swasheck J'énonce explicitement les trois choses que je recherche. Je fixe également des limites à ce que je ne cherche pas.
Trispé le

Réponses:

36

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 @MinutesToAddcontre le 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 réfléchir à la façon dont vous souhaitez gérer les calculs qui conduisent à l'un @EndTimeou aux deux @StartTimeet @EndTimeêtre 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 DATEADDest 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, dedans TIME, TIMEdehors.

Aaron Bertrand
la source
1
+1 @Aaron Alternativement, vous pouvez convertir StartTime et TimeToAdd en datetime puis ajouter. La conversion de TimeToAdd sera très compliquée lorsque les minutes sont> 59. DATEADD est la meilleure solution.
Brian
Si vous ajoutez qui DATEADDrenvoie le même type que l'argument date, j'accepterai. Le message "Empêcher le débordement si nécessaire?" la ligne n'est pas nécessaire. Le problème de roulement sera géré par la source des données et la destination des données.
Trisped
3
@Trisped bien sûr, si vous ajoutez à la question que vous ne pensiez pas que DATEADD était approprié parce que vous pensiez qu'il ne pouvait renvoyer que DATETIME et que cela pouvait causer des problèmes. Sinon, cela ne semble pas pertinent pour votre question ou pour les futurs lecteurs ...
Aaron Bertrand
Comment la pertinence n'est-elle pas impliquée par le "Veuillez noter que j'utilise le type de données de temps."? Aussi, pourquoi avez-vous changé ma question pour utiliser de manière inconstante la ligne au lieu de l'enregistrement?
Trisped
1
@Trisped la modification utilise une meilleure terminologie et veuillez consulter la FAQ sur la modification - les fiches n'ont plus de va-et-vient ou je verrouillerai la question. Aaron a raison de dire que nous devons tout clarifier pour les autres, vous avez votre réponse. Veuillez envisager de modifier votre question dans le sens qu'il suggère si vous pensez que cela serait utile: Aaron a aimablement proposé d'ajouter les informations que vous souhaitez à sa réponse si vous le faites.
Jack dit d'essayer topanswers.xyz le
0

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

Sélectionnez 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

Jun Sato
la source