Como adiciono minutos a um tipo de dados de hora?

10

Eu tenho um procedimento armazenado que insere dois registros em uma tabela, a diferença entre os registros é que a coluna de tempo do segundo registro é @MinToAddposterior ao primeiro:

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

O que é a maneira correta de adicionar @MinutesToAddminutos para @StartTimee @EndTime?
Observe que estou usando o timetipo de dados.

Atualização :
uma resposta correta deve conter as seguintes informações:

  • Como adicionar minutos a um timetipo de dados.
  • Que a solução proposta não resulta em perda de precisão.
  • Questões ou preocupações a serem observadas no caso de os minutos serem muito grandes para caberem em uma timevariável ou o risco de rolar a timevariável. Se não houver problemas, informe-o.
Trisped
fonte
5
Não vejo como sua edição da sua pergunta esclarece mais a questão em questão.
swasheck
@swasheck Indico explicitamente as três coisas que estou procurando. Também estabeleço limites para o que não estou procurando.
Trisped

Respostas:

36

Você não pode usar aritmética abreviada de taquigrafia com os novos tipos. Tentar:

DATEADD(MINUTE, @MinutesToAdd, @StartTime)

Observe que, embora você tenha protegido o seu @MinutesToAddestouro, você não protegeu o resultado do estouro. Isso não gera um erro, no entanto, pode não ser o resultado esperado.

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

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

Resultado:

00:19:00

Presumo que isso deva passar por algum tipo de conversão interna, porque você não conseguiu esse resultado dizendo:

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

Resultado:

Mensagem 241, nível 16, estado 1, linha 1
Falha na conversão ao converter data e / ou hora da cadeia de caracteres.

Você precisa considerar como deseja lidar com os cálculos que levam a um @EndTimeou ambos @StartTimee @EndTimea realizar no dia seguinte.

Além disso - para abordar outro novo requisito em sua "resposta ideal" - não há perda de precisão. De acordo com a documentação , o tipo de retorno de DATEADDé o mesmo que a entrada:

O tipo de dado de retorno é o tipo de dado do argumento de data , exceto os literais de sequência.

Portanto, TIMEdentro, TIMEfora.

Aaron Bertrand
fonte
11
+1 @Aaron Como alternativa, você pode converter StartTime e TimeToAdd em datetime e, em seguida, adicionar. A conversão de TimeToAdd será muito complicada quando os minutos forem> 59. DATEADD é a melhor solução.
Brian
Se você adicionar o que DATEADDretorna o mesmo tipo que o argumento de data, aceitarei. O "Impedir estouro, se necessário?" linha não é necessária. O problema de rolagem será tratado pela origem dos dados e pelo destino dos dados.
Trisped
3
@ Com certeza, se você adicionar à pergunta que não achou o DATEADD adequado, porque achou que ele poderia retornar apenas DATETIME e que isso poderia causar problemas. Caso contrário, não parece relevante para a sua pergunta ou para futuros leitores ...
Aaron Bertrand
Como a relevância não está implícita no item "Observe que estou usando o tipo de dados de hora". Além disso, por que você mudou minha pergunta para usar inconstantemente linha em vez de registro?
Trisped
11
@Trisped a edição usa uma terminologia melhor e consulte as perguntas frequentes sobre a edição - não temos mais informações sobre o assunto, ou vou bloquear a pergunta. Aaron está certo de que precisamos esclarecer tudo para os outros, você tem a sua resposta. Por favor, considere editar sua pergunta ao longo das linhas sugeridas por ele, se você acha que seria útil: Aaron se ofereceu para adicionar as informações que você deseja à resposta dele, se desejar.
Jack diz que tente topanswers.xyz
0

Basta usar a função dateadd para adicionar seus minutos em número inteiro contra '0:00'. Depois, volte ao tempo.

Selecionar elenco (datados (minutos, 84, '0: 00') como hora)

Aqui, 84 é o minuto inteiro que eu quero que seja expresso no tipo "hora".

Eu adicionei isso a '0:00' e, para remover o componente de data, eu o converto no tipo de hora. Não é necessária codificação personalizada.

(Sem nome da coluna)

01: 24: 00.0000000

Jun Sato
fonte