2012-05-01 10 views
14
declare @str_datetime varchar(50) 
set @str_datetime='30-04-2012 19:01:45' -- 30th April 2012 
declare @dt_datetime datetime 
select @[email protected]_datetime 

Dies gibt folgende Fehlermeldung:Wie entscheidet SQL Server über das Format für die implizite Datetime-Konvertierung?

Msg 242, Level 16, State 3, Line 4
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

Meine Frage ist, wie SQL Server entscheiden, welches Format für implizite Datetime-Konvertierung zu verwenden?

Antwort

23

Dies kann von einer Vielzahl von Faktoren abhängen - den regionalen Einstellungen des Betriebssystems, der Sprache und dem Datumsformat des aktuellen Benutzers. Standardmäßig verwendet Windows US English, und die Benutzereinstellungen sind US English und MDY.

Aber hier sind einige Beispiele, um zu zeigen, wie sich das ändern kann.

Mitglied ist BRITISH Spracheinstellungen:

-- works: 
SET LANGUAGE BRITISH; 
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45'); 

-- fails: 
SELECT CONVERT(DATETIME, '04/13/2012'); 
GO 

(Fehler)

Msg 242, Level 16, State 3, Line 5
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

Benutzer verwendet Français:

-- works: 
SET LANGUAGE FRENCH; 
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45'); 

-- fails: 
SELECT CONVERT(DATETIME, '04/13/2012'); 
GO 

(Fehler)

Msg 242, Level 16, State 3, Line 1
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.

Benutzer verwendet wieder Français:

SET LANGUAGE FRENCH; 

-- fails (proving that, contrary to popular belief, YYYY-MM-DD is not always safe): 
SELECT CONVERT(DATETIME, '2012-04-30'); 
GO 

(Fehler)

Msg 242, Level 16, State 3, Line 1
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.

Nutzer ist DMY statt MDY mit:

SET LANGUAGE ENGLISH; 
SET DATEFORMAT DMY; 

-- works: 
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45'); 

-- fails: 
SELECT CONVERT(DATETIME, '04-30-2012'); 
GO 

(Fehler)

Msg 242, Level 16, State 3, Line 2
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

Ihre beste Wahl ist immer die Verwendung von ISO-Standard, nicht-regionalen, sicheren und eindeutigen Datumsformaten. Die beiden ich in der Regel empfehlen sind:

YYYYMMDD     - for date only. 
YYYY-MM-DDTHH:MM:SS[.mmm] - for date + time, and yes that T is important. 

Keines dieser fehlschlagen:

SET DATEFORMAT MDY; 
SET LANGUAGE ENGLISH; 
SELECT CONVERT(DATETIME, '20120430'); 
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45'); 
SET LANGUAGE FRENCH; 
SELECT CONVERT(DATETIME, '20120430'); 
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45'); 
SET LANGUAGE BRITISH; 
SELECT CONVERT(DATETIME, '20120430'); 
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45'); 
SET DATEFORMAT DMY; 
SELECT CONVERT(DATETIME, '20120430'); 
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45'); 

Daher empfehle ich, dass stark, anstatt dass Benutzer eingeben Textdatumsformate (oder dass Sie selbst unzuverlässig Formate), kontrollieren Sie Ihre Eingabezeichenfolgen und stellen Sie sicher, dass sie sich an eines dieser sicheren Formate halten. Dann ist es egal, welche Einstellungen der Benutzer hat oder was die zugrunde liegenden regionalen Einstellungen sind, Ihre Daten werden immer als die Daten interpretiert, für die sie bestimmt waren.Wenn Sie derzeit zulassen, dass Benutzer Daten in ein Textfeld in einem Formular eingeben, beenden Sie dies und implementieren Sie ein Kalendersteuerelement oder mindestens eine Auswahlliste, damit Sie das Zeichenfolgenformat, das an SQL Server zurückgegeben wird, endgültig steuern können.

Für einige Hintergrund lesen Tibor Karaszi des "The ultimate guide to the datetime datatypes" und meinen Beitrag "Bad Habits to Kick : Mis-handling date/range queries."

+0

Siehe meine Antwort [hier] (http://Stackoverflow.com/a/23369706/2108149), wie man es innerhalb einer benutzerdefinierten Funktion macht. –

+2

@Eli Ich denke, du verpasst den Punkt, den ich versucht habe zu machen. Wenn eine Person in England ist und eine Zeichenfolge '09/04/2014 'übergibt und eine andere Person in den USA ist und die '09/04/2014' übergibt, wie kann Ihre Funktion auf magische Weise wissen, welche davon den 9. April und welche gemeint hat bedeutete 4. September? –

+0

Ich muss zugeben, dass ich Ihren ganzen Thread nicht gelesen habe, ich suchte nach einer Monatsübersetzungslösung und während ich danach suchte, bin ich auf Ihre Antwort gestoßen, also dachte ich, manche Leute könnten es hilfreich finden ... –

1

By default, the date format for SQL server is in U.S. date format MM/DD/YY, unless a localized version of SQL Server has been installed. This setting is fine for cases when an application that requires this functionality is deployed in a manner guaranteeing that dates are used and inserted in the same format across all platforms and locations where the application is used.

However, in some cases the date must be in a DD/MM/YY format because many countries/regions use this format rather than the U.S. default of MM/DD/YY. This is especially an issue for international applications that are distributed all over the world.

Source

Also, was Sie tun müssen, bevor die Hand, das Datumsformat eingestellt ist, wie so:

SET DATEFORMAT dmy 
GO 

Und dann wird Ihre Anfrage arbeiten.

+0

... bis jemand ein anderes Format verwendet. –

+1

@AaronBertrand Korrekt. Gibt es irgendwelche unfehlbaren Ansätze, um dies auf SQL zu behandeln? Ich meine, erhalte eine Zeichenfolge, die ein Datum in einem beliebigen Format darstellt, und führe die Konvertierung sicher durch, ohne irgendeine böse Logik? – Icarus

+1

Nein, gibt es nicht. Sie müssen die Eingabezeichenfolge steuern. Wenn ein Benutzer "05/06/2012" übergibt, weil er sie in einem beliebigen Format eingeben darf, wie kann SQL Server dann zuverlässig feststellen, ob der Benutzer den 6. Mai oder den 5. Juni gemeint hat? –

1

Sie können auch für jede Logins und/oder für jede zukünftige Anmeldungen de Standard-Datumsformat ändern hinzugefügt (ohne die Bedürfnisse zu tun „SET DATEFORMAT“ bitte in jeder Sitzung.

gehen Sie in SQL Management Studio/Security/Logins. Rechts-clic das Login, dann auf Eigenschaften. Sie werden am unteren Rand "Standardsprache" sehen.

Wenn Sie sicher, dass jeder machen wollen Logins, die in Zukunft hinzugefügt werden, erhalten die "gute" Sprache. Sie klicken mit der rechten Maustaste auf Ihrem Server root, dann die Seite Eigenschaften und Erweitert. Dort gibt es auch eine Option "Standardsprache", die für neu erstellte Logins verwendet wird.

+0

Sie sollte nicht nur "danke" hier kommentieren .... aber ich muss, also: danke. – Steen

Verwandte Themen