Crie uma data do dia mês e ano com o T-SQL
Estou tentando converter uma data com partes individuais, como 12, 1, 2007, em um datetime no SQL Server 2005. Tentei o seguinte:
mas isso resulta na data errada. Qual é a maneira correta de transformar os três valores de data em um formato de data e hora adequado.
Por favor, considere alterar sua resposta aceita weblogs.sqlteam.com/jeffs/archive/2007/09/10/…
DATEFROMPARTS (ano, mês, dia)
Supondo que y, m, dsejam todos int, que tal:
Por favor, veja minha outra resposta para o SQL Server 2012 e acima
Mau. Escreva-me a partir de ints na data de 1º de janeiro de 0001
Oleg SQL Server DateTime não vá mais longe, então 1753-01-01 algo.
— CodeMonkey 01/07/2013
Esta resposta depende das configurações de formato de data, que dependem das configurações regionais do seu servidor, se você não especificar. O yyyymmddformato funciona independentemente dessas configurações. "Uma cadeia de seis ou oito dígitos é sempre interpretada como ymd ." docs.microsoft.com/en-us/sql/t-sql/data-types/… Consulte esta resposta: stackoverflow.com/a/46064419/2266979
— Riley Major
Funciona também, tem o benefício adicional de não fazer nenhuma conversão de string, por isso é um processamento aritmético puro (muito rápido) e não depende de nenhum formato de data. valor da parte cuja primeira parte é um número inteiro que representa o número de dias desde 1 de janeiro de 1900 e a segunda parte é uma fração decimal que representa a parte fracionária de um dia (para a hora) --- Portanto, o valor inteiro 0 (zero ) sempre se traduz diretamente na manhã da meia-noite de 1 de janeiro de 1900 ...
ou, graças à sugestão do @brinary,
Editado em outubro de 2014. Conforme observado pelo @cade Roux, o SQL 2012 agora tem uma função interna:
isso faz a mesma coisa.
Editado em 3 de outubro de 2016, (Obrigado a @bambams por perceber isso e @brinary por corrigi-lo), A última solução, proposta por @brinary. parece não funcionar por anos bissextos, a menos que a adição de anos seja realizada primeiro
@Brandon, você deve marcar isso como esta resposta. É o melhor. Faça isso como um serviço para outros leitores do StackOverflow.
— Bill Paetzke
Funciona por anos bissextos: selecione dateadd (mm, (@ y-1900) * 12 + @m - 1,0) + (@ d-1)
Resulta em um valor de data válido, porém falso, quando passado uma combinação inválida de valores @Year = 2001, por exemplo , @Month = 13e @DayOfMonth = 32resulta em 2002-02-01T00:00:00.000. A resposta aceita (por Cade Roux) gera um erro, o que é mais útil.
Você não precisa começar com zero e adicionar dias. Você pode começar diretamente com @ DayOfMonth-1 e adicionar os meses e anos. Isso é menos um DateAdd ()!
minha cabeça ainda está girando - realmente não há uma maneira mais clara de fazer isso? (Eu estou encarregado de fixar uma consulta no SQL Server 2005)
— Peter Perháč
O SQL Server 2012 possui uma nova e maravilhosa função DATEFROMPARTS (que gerará um erro se a data for inválida - minha principal objeção a uma solução baseada em DATEADD para esse problema):
Além disso, referindo-se à pergunta original, onde o objeto Datetime foi mencionado, também há uma função chamada DATETIMEFROMPARTS: msdn.microsoft.com/pl-pl/library/hh213233%28v=sql.110%29.aspx
— Maciej Jaśniaczyk
Ou usando apenas uma única função dateadd:
— Picanço
melhor resposta IMO. Tem todas as vantagens da resposta de Charles e é muito mais curto.
Este é de longe o mais limpo e mais simples. E isso não gera um erro quando os valores do dia também estão fora da faixa. Embora, dependendo da circunstância, um erro possa ser desejado, lembre-se de que isso silencia valores de dia e mês que estão fora do intervalo esperado.
— Shawn Kovac
O Sql Server 2012 possui uma função que criará a data com base nas partes ( DATEFROMPARTS ). Para o resto de nós, aqui está uma função db que criei que determinará a data das partes (obrigado @Charles) ...
Você pode chamar assim ...
Retorna ...
Tente CONVERT em vez de CAST.
CONVERT permite um terceiro parâmetro indicando o formato da data.
A lista de formatos está aqui: http://msdn.microsoft.com/en-us/library/ms187928.aspx
Atualizar após outra resposta ter sido selecionada como a resposta "correta":
Realmente não entendo por que uma resposta é selecionada que depende claramente das configurações de NLS do seu servidor, sem indicar essa restrição.
— devio
Concorde que o formato precisa ser qualificado, por exemplo, CONVERT (datetime2, CAST (@ano AS varchar) + '.' + CAST (@month AS varchar) + '.' + CAST (@day AS varchar), 102)
Funciona no SQL desde a versão 2012 e AzureSQL
— Marcelo Lujan
É mais seguro e organizado usar um ponto de partida explícito '19000101'
Por que não usar apenas declare @output datetime2 = 0e em vez de @Year - 1900usar @Year - DATEPART(year,0);? Isso funciona sem nenhuma conversão no SQL Server 2008 e muito mais claro.
— Tsionyx #
Porque isso não vai funcionar. Você não pode converter 0 em datetime2. Seu código retornará "Operand type clash: int é incompatível com datetime2"
Se você não deseja manter as strings fora dele, isso também funciona (coloque-o em uma função):
Eu adiciono uma solução de uma linha se você precisar de um datetime de partes de data e hora :
— Saul Guerra
Para versões do SQL Server abaixo de 12, recomendo o uso CASTem combinação comSET DATEFORMAT
como você cria essas strings é com você
— user3141962
Eu sei que o OP está pedindo a resposta do SQL 2005, mas a pergunta é bastante antiga; portanto, se você estiver executando o SQL 2012 ou superior, poderá usar o seguinte:
Referência: https://docs.microsoft.com/en-us/sql/t-sql/functions/eomonth-transact-sql?view=sql-server-2017&viewFallbackFrom=sql-server-previousversions
— Peter Bojanczyk
Pessoalmente, prefiro o Substring, pois fornece opções de limpeza e capacidade de dividir o texto conforme necessário. A suposição é que os dados tenham o formato 'dd, mm, aaaa'.
Aqui está uma demonstração de como ele pode ser processado se os dados forem armazenados em uma coluna. Escusado será dizer que é ideal verificar o conjunto de resultados antes de aplicar na coluna