SQL: la conversione di un tipo di dati varchar in un tipo di dati datetime ha prodotto un valore fuori intervallo


96

Ho ricevuto il seguente errore durante l'esecuzione di un SQL per convertire il valore del mio tipo di dati da varchara datetime.

Msg 242, livello 16, stato 3, riga 1 La conversione di un tipo di dati varchar in un tipo di dati datetime ha prodotto un valore fuori intervallo.

Ho controllato i dati e non riesco a vedere nulla di strano: ho eseguito i seguenti controlli e tutti non hanno restituito risultati

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

C'è qualcos'altro che valga la pena guardare e forse vale la pena suggerire o aiutare con questo problema? Non riesco a capirlo.


3
Qual è il tipo di dati della colonna della data? Potresti mostrarmi lo schema della tabella e l'affermazione in cui si verifica l'errore, per favore?
Spikeh

3
quale delle sei istruzioni SQL fornite non riesce?
Mureinik

1
Le sei dichiarazioni funzionano tutte e non verificano problemi con i dati.
user23495

3
non hai verificato le date non valide, ad esempio 31-10-2013 o 30-02-2013. Probabilmente, l'errore che stai affrontando, si riferisce a quel tipo di date problematiche
Dalen

2
Ciao Dalen, ho fatto questo controllo. La modalità di impostazione dei dati è il 31/10/2013, il 30/10/2013. È in formato UK. Ciò avrà alcun impatto quando si tenta di modificare un tipo di colonna, non pensavo che sarebbe stato così.
user23495

Risposte:


90

Ho affrontato lo stesso problema una settimana fa. Il problema è con l'impostazione del fuso orario. Specificare in altri formati come mm / gg / aaaa (di solito funziona).

Specificare la data come 30/12/2013 ha provocato l'errore per me. Tuttavia, specificarlo come formato mm / gg / aaaa ha funzionato.

Se hai bisogno di convertire il tuo input, puoi provare a guardare nel CONVERTmetodo. La sintassi è

CONVERT(VARCHAR,@your_date_Value,103)

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

La finitura 103 è il formato datetime.

Fare riferimento a questo collegamento per i formati di conversione e ulteriori letture. https://www.w3schools.com/sql/func_sqlserver_convert.asp


1
Grazie per l'aiuto amico. Ho provato a convertirlo ma non ho ancora avuto fortuna. Potrebbe essere dovuto al fatto che la tabella è un varchar ancora o qualsiasi altra cosa che possa causare il fallimento?
user23495

2
Sarebbe molto utile se pubblichi i tuoi dati di esempio (che sono nella tabella). Nel commento hai detto di volerlo in formato aaaa-mm-gg. Quindi, prova questo SELECT CONVERT(char(10), GetDate(),126). Basta sostituire GETDATE () con il valore necessario.
Mahe

61

Mi sono imbattuto in questo problema a causa di uno stupido errore. Assicurati che la data esista effettivamente!

Per esempio:

31 settembre 2015 non esiste.

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

Quindi questo fallisce con il messaggio:

Error converting data type varchar to datetime.

Per risolverlo, inserisci una data valida:

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

E funziona bene.


2
Sì, ho appena trovato una data di scadenza del 29 febbraio 2015 nel database con cui devo lavorare. Mi chiedo come sia finito lì. Mi chiedo quanti altri ci siano ...
Risorsa

4
Ho appena usato cast (SUBSTRING ([MyDateField], 1,2) come intero)> 31 e ho trovato un record con il 60 dicembre. Chi entra in questa roba, dottor Suess?
SteveCav

3
Grazie! Questo era il mio problema. Ho avuto dei cattivi dati nel mio set - 01/01/1113, haha.
Sev09

2
Per me, avevo inserito la stringa di formato errata durante la formattazione della data per creare l'istruzione SQL. Avevo usato Format(DateTime.Now, "yyyymmdd")quando avrebbe dovuto essereFormat(DateTime.Now, "yyyyMMdd")
Jay Imerman il

1
Convenzioni americane di data Argh! Mi ha lasciato perplesso per un po ', dal momento che "26 ottobre 2017" cioè '26-10-2017' è una data perfettamente valida :)
Antimonio

31

Ho avuto un problema simile di recente. Le impostazioni regionali sono state configurate correttamente sia nell'app che nel server di database. Tuttavia, l'esecuzione di SQL ha provocato

"La conversione di un tipo di dati varchar in un tipo di dati datetime ha prodotto un valore fuori intervallo".

Il problema era la lingua predefinita dell'utente db.

Per verificarlo o modificarlo in SSMS, vai su Sicurezza -> Accessi e fai clic con il pulsante destro del mouse sul nome utente dell'utente che esegue le query. Seleziona proprietà -> generale e assicurati che la lingua predefinita nella parte inferiore della finestra di dialogo sia quella che ti aspetti.

Ripeti l'operazione per tutti gli utenti che eseguono query.


2
Questo mi ha aiutato. Solo una piccola correzione: lingua predefinita del server loginnon db user. top-password.com/blog/…
Baz Guvenkaya

1
Dato che era impostato nel codice del programma e non avevo accesso al codice, l'ho cambiato da Englisha British Englishe ha funzionato!
vaheeds

1
Lo stesso per me e per cambiare l'inglese all'inglese britannico - Ali, sei un salvavita!
david-giorgi


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)))

5
Si prega di aggiungere più descrizione alla risposta. Aiuterà l'interrogante a cogliere di più dalla tua risposta.
Pramod S. Nikam

2

Ho avuto lo stesso problema e ho stabilito che questo problema si verifica perché SQL Server non esegue confronti sui caratteri convertiti in numeri interi in modo identico. Nel mio test, ho scoperto che alcuni confronti di caratteri convertiti, come il punto esclamativo, restituiranno errori di conversione del tipo, mentre altri confronti di caratteri convertiti, come lo spazio, saranno determinati fuori intervallo.

Questo codice di esempio verifica i diversi scenari possibili e presenta una soluzione utilizzando istruzioni REPLACE nidificate. Il REPLACE determina se ci sono caratteri nella stringa che non sono numeri o barra e, se esiste, la lunghezza della stringa sarà maggiore di zero, indicando così che ci sono caratteri 'cattivi' e la data non è valida .

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

Produzione:

--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

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

Aveva una riga problematica con la stringa della data "19610010" (formato: AAAAMMGG) che causava l'errore "La conversione di un tipo di dati nvarchar in un tipo di dati datetime ha generato un valore fuori intervallo". SELEZIONA CONVERT (datetime, 'yourdate') FROM [yourdate] WHERE ISDATE ('yourdate') = 1 ha salvato la giornata :)
J Pollack

2

Anch'io ho riscontrato questo problema durante l'inserimento automatico di un sysdate in una colonna.

Quello che ho fatto è stato cambiare il formato della data del mio sistema in modo che corrispondesse al formato della data del server SQL. es. il mio formato SQL era mm / gg / aaaa e il formato del mio sistema era impostato su gg / mm / aaaa. Ho cambiato il formato del mio sistema in mm / gg / aaaa e l'errore è sparito

-kb


2

Come sai, questo è un problema di formato britannico. È possibile eseguire la conversione della data indirettamente utilizzando la funzione.

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

Per chiamare questa funzione

SELECT dbo.ChangeDateFormatFromUK([dates]) from table

Converti normalmente in datetime

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

Nel tuo caso, puoi farlo

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

2

Test per l'anno> 2079. Ho scoperto che un utente ha digitato 2106 invece del 2016 nell'anno (10/12/2106) e boom; così il 10/12/2016 ho testato e ho trovato SQL Server accettato fino al 2078, ho iniziato a lanciare quell'errore se l'anno è 2079 o superiore. Non ho fatto ulteriori ricerche sul tipo di data scorrevole di SQL Server.


1

Ho semplicemente convertito il campo varchar che volevo convertire in una nuova tabella (con un file DateTime) in un layout compatibile con DateTime prima e poi SQL eseguirà la conversione da varchar a DateTime senza problemi.

Di seguito (non la mia tabella creata con quei nomi!) Faccio semplicemente che il campo varchar sia un sosia di DateTime se vuoi:

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)  

1
Varchar Date Convert to Date and Change the Format

12 nov 2016 12:00, 21/12/2016, 21-12-2016 questa query funziona per sopra per passare a questo formato gg / MM / aaaa SELECT [Member_ID],[Name] , Convert(varchar(50),Convert(date,[DOB],103),103) as DOB ,[NICNO],[Relation] FROM [dbo].[tbl_FamilMember]


0

Questo errore si è verificato per me perché stavo cercando di memorizzare la data e l'ora minime in una colonna utilizzando query inline direttamente dal codice C #.

La variabile della data è stata impostata su 01/01/0001 12:00:00 AM nel codice dato il fatto che DateTime in C # è inizializzato con questa data e ora se non impostato altrimenti. E la data meno possibile consentita nel tipo di dati datetime di MS-SQL 2008 è 1753-01-01 12:00:00 AM.

Ho cambiato la data dal codice e l'ho impostata su 01/01/1900 e non sono stati segnalati ulteriori errori.


0

Ho usato ToString () su una data con mm invece di MM.


0

Assicurati solo che le tue date siano compatibili o che possano essere eseguite correttamente nel tuo database manager (es. SQL Server Management Studio). Ad esempio, la funzione DateTime.Now C # non è valida in SQL Server, il che significa che la query deve includere funzioni valide come GETDATE () per SQL Server.

Questo cambiamento ha funzionato perfettamente per me.


0

Causa leggermente insolita per questo problema, ma nel caso qualcuno ne avesse bisogno. Il codice su cui stavo lavorando stava usando:

java.text.DateFormat.getDateTimeInstance()

per ottenere un formattatore di data. Il modello di formattazione restituito da questa chiamata è cambiato da Java 8 a Java 9 come descritto in questo bug report: https://bugs.openjdk.java.net/browse/JDK-8152154 apparentemente la formattazione che stava restituendo per me non era adatta per il database. La soluzione era invece a questo:

DateTimeFormatter.ISO_LOCAL_DATE_TIME
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.