SQL - A conversão de um tipo de dados varchar em um tipo de dados datetime resultou em um valor fora do intervalo

87

Tenho recebido o seguinte erro ao executar um SQL para converter meu valor de tipo de dados de varcharem datetime.

Msg 242, Nível 16, Estado 3, Linha 1 A conversão de um tipo de dados varchar em um tipo de dados datetime resultou em um valor fora do intervalo.

Eu verifiquei os dados e não consigo ver nada estranho: execute as seguintes verificações e todas não retornam resultados

SELECT [Date] from table where [DATe] is null
SELECT [Date] from table where [DATe] = ''
SELECT [Date] from table where LEN([date])> 10
SELECT [Date] from table where LEN([date])< 10
SELECT top 100 [Date] , SUBSTRING([date],4,2) from [table where convert(int, SUBSTRING([date],4,2)) < 1 or convert(int, SUBSTRING([date],4,2)) > 12
SELECT top 100 [Date] , SUBSTRING([date],1,2) from table where convert(int, SUBSTRING([date],4,2)) < 1 or convert(int, SUBSTRING([date],4,2)) > 31

Há mais alguma coisa que valha a pena olhar e talvez valha a pena alguma indicação ou ajuda com esse problema? Não consigo entender isso.

user23495
fonte
3
Qual é o tipo de dados da coluna de data? Você poderia me mostrar o esquema da tabela e a instrução em que o erro ocorre, por favor?
Spikeh
3
qual das seis instruções SQL que você forneceu falha?
Mureinik
1
Todas as seis instruções funcionam e não verificam problemas com os dados.
user23495
3
você não verificou datas não válidas, por exemplo, 31/10/2013 ou 30/02/2013. Provavelmente, o erro que você está enfrentando refere-se a esse tipo de datas problemáticas
Dalen
2
Oi Dalen, eu fiz essa verificação. A forma como os dados são configurados é 31/10/2013, 30/10/2013. Está no formato do Reino Unido. Isso terá algum impacto ao tentar alterar um tipo de coluna, não pensei que teria.
user23495

Respostas:

84

Eu enfrentei o mesmo problema há uma semana. O problema está na configuração do fuso horário. Especifique em outros formatos como mm / dd / aaaa (geralmente funciona).

Especificando a data como 30/12/2013 resultou em erro para mim. No entanto, especificá-lo como o formato mm / dd / aaaa funcionou.

Se precisar converter sua entrada, você pode tentar examinar o CONVERTmétodo. Sintaxe é

CONVERT(VARCHAR,@your_date_Value,103)

CONVERT(VARCHAR, '12/30/2013', 103)

O final 103 é o formato datetime.

Consulte este link para formatos de conversão e outras leituras. https://www.w3schools.com/sql/func_sqlserver_convert.asp

Mahe
fonte
1
Obrigado pela ajuda companheiro. Tentei converter, mas ainda não tive sorte. Será que a tabela ainda é um varchar ou qualquer outra coisa que pode causar falha?
user23495
2
Seria muito útil se você postar seus dados de amostra (que estão na tabela). No comentário, você disse que deseja no formato aaaa-mm-dd. Então, tente isso SELECT CONVERT(char(10), GetDate(),126). Basta substituir GETDATE () pelo valor necessário.
Mahe
60

Corri para esse problema devido a um erro bobo. Certifique-se de que a data realmente existe!

Por exemplo:

31 de setembro de 2015 não existe.

EXEC dbo.SearchByDateRange @Start = '20150901' , @End = '20150931'

Portanto, isso falha com a mensagem:

Error converting data type varchar to datetime.

Para consertar, insira uma data válida:

EXEC dbo.SearchByDateRange @Start = '20150901' , @End = '20150930'

E ele executa muito bem.

Sr. C
fonte
2
Sim, acabei de encontrar uma data de validade de 29 de fevereiro de 2015 no banco de dados com o qual tenho que trabalhar. Eu me pergunto como isso entrou lá. Eu me pergunto quantos mais estão aí ...
Recurso
4
Acabei de usar cast (SUBSTRING ([MyDateField], 1,2) como inteiro)> 31 e encontrei um registro com o dia 60 de dezembro. Quem entra nessa coisa, Dr. Suess?
SteveCav
3
Obrigado! Esse era o meu problema. Eu tinha alguns dados ruins no meu conjunto - 01/01/1113, haha.
Sev09
2
Para mim, coloquei a string de formato incorreta ao formatar a data para construir a instrução SQL. Eu usei Format(DateTime.Now, "yyyymmdd")quando deveriaFormat(DateTime.Now, "yyyyMMdd")
Jay Imerman
1
Argh convenções de data americanas! Me deixou perplexo por um tempo, já que "26 de outubro de 2017", ou seja, '26 -10-2017 'é uma data perfeitamente válida :)
Antimônio
29

Tive um problema semelhante recentemente. As configurações regionais foram configuradas corretamente no aplicativo e no servidor de banco de dados. No entanto, a execução de SQL resultou em

"A conversão de um tipo de dados varchar em um tipo de dados datetime resultou em um valor fora do intervalo".

O problema era o idioma padrão do usuário db.

Para verificar ou alterar no SSMS, vá para Segurança -> Logins e clique com o botão direito do mouse no nome de usuário do usuário que executa as consultas. Selecione propriedades -> geral e certifique-se de que o idioma padrão na parte inferior da caixa de diálogo é o que você espera.

Repita isso para todos os usuários que executam consultas.

todos
fonte
1
Isso me ajudou. Apenas uma pequena correção: linguagem padrão do server loginnot db user. top-password.com/blog/…
Baz Guvenkaya
1
Como ele foi definido no código do programa e eu não tive acesso ao código, mudei de Englishpara British Englishe funcionou!
vaheeds
1
O mesmo para mim, que mudaria de inglês para inglês britânico - Ali, você é um salva-vidas!
david-giorgi
10

Você pode fazer uso de

Set dateformat <date-format> ;

em sua função sp ou procedimento armazenado para fazer as coisas.

Sachin Mishra
fonte
1
Isso resolveu meu problema. O que não entendo é por que isso começou a acontecer de repente :(
VictorEspina
4
Create procedure [dbo].[a]

@examdate varchar(10) ,
@examdate1 varchar(10)
AS
Select tbl.sno,mark,subject1,
Convert(varchar(10),examdate,103) from tbl
where 
(Convert(datetime,examdate,103)  >= Convert(datetime,@examdate,103) 
and (Convert(datetime,examdate,103) <=  Convert(datetime,@examdate1,103)))
sonu yadav
fonte
5
Adicione mais descrição à sua resposta. Isso ajudará o questionador a compreender melhor sua resposta.
Pramod S. Nikam
2

Eu tive o mesmo problema e determinei que esse problema surge porque o SQL Server não executa comparações em caracteres convertidos em inteiros de maneira idêntica. Em meu teste, descobri que algumas comparações de caracteres convertidos, como o ponto de exclamação, retornarão erros de conversão de tipo, enquanto outras comparações de caracteres convertidos, como o espaço, serão determinadas como fora do intervalo.

Este código de amostra testa os diferentes cenários possíveis e apresenta uma solução usando instruções REPLACE aninhadas. O REPLACE determina se há algum caractere na string que não seja numeral ou barra e, se houver, o comprimento da string será maior que zero, indicando assim que existem caracteres 'ruins' e a data é inválida .

DECLARE @str varchar(10)
SET @str = '12/10/2012'
IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
    PRINT @str+': Passed Test'
    ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/10/2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string
PRINT ''
GO

DECLARE @str varchar(10)
SET @str = '12/!0/2012'
    IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
        PRINT @str+': Passed Test'
        ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/!0/2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string
PRINT ''
GO

DECLARE @str varchar(10)
SET @str = '12/  /2012'
IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
    PRINT @str+': Passed Test'
    ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/  /2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string

Resultado:

--Output
--12/10/2012: Passed Test
--Number of characters in 12/10/2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 0

--Msg 245, Level 16, State 1, Line 4
--Conversion failed when converting the varchar value '!0' to data type int.
--Number of characters in 12/!0/2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 1

--12/  /2012: Failed Test
--Number of characters in 12/  /2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 2
RSax
fonte
2
+ this happens because sql sometimes doesn't recognize dd/mm/yyyy format
+ so we should always check if the input string is a valid date or not and the accordingly convert it to mm/dd/yyyy and so , i have shown below how it can be done, i have created a function to rearrange in mm/dd/yyyy from dd/mm/yyyy

select case when isdate('yourdate')=1 then CAST('yourdate' AS datetime) 
  else (select * from dbo.fn_convertdate(yourdate))

Create function dbo.fn_convertdate( @Stringdate nvarchar(29))
RETURNS @output TABLE(splitdata NVARCHAR(MAX) 
)
Begin
Declare @table table(id int identity(1,1), data varchar(255))
Declare @firstpart nvarchar(255)
Declare @tableout table(id int identity(1,1), data varchar(255))

Declare @Secondpart nvarchar(255)
Declare @Thirdpart nvarchar(255)

declare @date datetime

insert into @table
select * from dbo.fnSplitString(@Stringdate,'/')
select @firstpart=data from @table where id=2
select @Secondpart=data from @table where id=1
select @Thirdpart=data from @table where id=3
set @date=@firstpart+'/'+@Secondpart+'/'+@Thirdpart
insert into @output(splitdata) values(
@date)


return
End
shashank m
fonte
Tinha uma linha problemática com string de data '19610010' (formato: AAAAMMDD) que causou o erro 'A conversão de um tipo de dados nvarchar em um tipo de dados datetime resultou em um valor fora do intervalo'. SELECT CONVERT (datetime, 'yourdate') FROM [yourtable] WHERE ISDATE ('yourdate') = 1 salvou o dia :)
J Pollack
2

Eu também encontrei esse problema ao inserir automaticamente um sysdate em uma coluna.

O que fiz foi alterar o formato de data do meu sistema para corresponder ao formato de data do servidor SQL. por exemplo, meu formato SQL era mm / dd / aaaa e meu formato de sistema foi definido como dd / mm / aaaa. Mudei o formato do meu sistema para mm / dd / aaaa e o erro desapareceu

-kb

user5714464
fonte
2

Como você sabe, este é um problema de formato do Reino Unido. Você pode fazer a conversão de data indiretamente usando a função.

CREATE FUNCTION  ChangeDateFormatFromUK
( 
   @DateColumn varchar(10)
)

RETURNS VARCHAR(10)
AS 
 BEGIN
    DECLARE @Year varchar(4), @Month varchar(2), @Day varchar(2), @Result varchar(10)
    SET @Year = (SELECT substring(@DateColumn,7,10))
    SET @Month = (SELECT substring(@DateColumn,4,5)) 
    SET @Day = (SELECT substring(@DateColumn,1,2))
   SET @Result  = @Year  + '/' @Month + '/' +  @Day

 RETURN @Result
END

Para chamar esta função

SELECT dbo.ChangeDateFormatFromUK([dates]) from table

Converta normalmente para data e hora

SELECT CONVERT(DATETIME,dbo.ChangeDateFormatFromUK([dates])) from table

No seu caso, você pode fazer

SELECT [dates] from table where CONVERT(DATETIME,dbo.ChangeDateFormatFromUK([dates])) > GetDate()   -- or any date
Sumit
fonte
2

Teste para o ano> 2079. Descobri que um usuário digitou 2106 em vez de 2016 no ano (10/12/2106) e boom; então em 12/10/2016 testei e encontrei SQL Server aceito até 2078, comecei a lançar aquele erro se o ano for 2079 ou superior. Não fiz nenhuma pesquisa adicional sobre que tipo de deslizamento de data o SQL Server faz.

Gordon
fonte
1

Simplesmente converti o campo varchar que queria converter em uma nova tabela (com um campo DateTime) para um layout compatível com DateTime primeiro e, em seguida, o SQL fará a conversão de varchar em DateTime sem problemas.

Abaixo (não minha tabela criada com esses nomes!), Eu simplesmente torno o campo varchar parecido com DateTime se você quiser:

update report1455062507424 
set [Move Time] = substring([Move Time], 7, 4) + '-'+ substring([Move Time], 4, 2) + '-'+ substring([Move Time], 1, 2) + ' ' + 
    substring([Move Time], 12, 5)  
Andre
fonte
1
Varchar Date Convert to Date and Change the Format

12 de novembro de 2016 12:00, 21/12/2016, 21-12-2016 esta consulta funciona para acima para alterar para este formato dd / MM / aaaa SELECT [Member_ID],[Name] , Convert(varchar(50),Convert(date,[DOB],103),103) as DOB ,[NICNO],[Relation] FROM [dbo].[tbl_FamilMember]

Khalid
fonte
0

Este erro ocorreu para mim porque eu estava tentando armazenar a data e a hora mínimas em uma coluna usando consultas inline diretamente do código C #.

A variável de data foi definida como 01/01/0001 12:00:00 AM no código devido ao fato de que DateTime em C # é inicializado com esta data e hora se não for definido de outra forma. E a menor data possível permitida no tipo de dados datetime MS-SQL 2008 é 1753-01-01 12:00:00 AM.

Mudei a data do código e configurei para 01/01/1900 e nenhum erro foi relatado.

Talha Imam
fonte
0

Usei ToString () em um encontro com mm em vez de MM.

L0uis
fonte
0

Apenas certifique-se de que suas datas são compatíveis ou podem ser executadas corretamente em seu gerenciador de banco de dados (por exemplo, SQL Server Management Studio). Por exemplo, a função DateTime.Now C # é inválida no servidor SQL, o que significa que sua consulta deve incluir funções válidas como GETDATE () para SQL Server.

Essa mudança funcionou perfeitamente para mim.

tonderaimuchada
fonte
0

Causa um pouco incomum para esse problema, mas apenas no caso de alguém precisar. O código em que estava trabalhando estava usando:

java.text.DateFormat.getDateTimeInstance()

para obter um formatador de data. O padrão de formatação retornado por esta chamada mudou de Java 8 para Java 9 conforme descrito neste relatório de bug: https://bugs.openjdk.java.net/browse/JDK-8152154 aparentemente a formatação que estava retornando para mim não era adequada para o banco de dados. Em vez disso, a solução foi:

DateTimeFormatter.ISO_LOCAL_DATE_TIME
Wobblycogs
fonte