Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie entscheidet SQL Server über das Format für die implizite Datetime-Konvertierung?

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

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

Der Benutzer verwendet BRITISCHE Spracheinstellungen:

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

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

(Fehler)

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)

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

Der Benutzer verwendet DMY anstelle von MDY:

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)

Am besten verwenden Sie immer nicht regionale, sichere und eindeutige Datumsformate nach ISO-Standard. Die zwei, die ich normalerweise empfehle, sind:

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

Keines davon schlägt fehl:

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 dringend, dass Sie Ihre Eingabezeichenfolgen kontrollieren und sicherstellen, dass sie einem dieser sicheren Formate entsprechen, anstatt Benutzer Freitext-Datumsformate eingeben zu lassen (oder dass Sie selbst unzuverlässige Formate verwenden). Dann spielt es keine Rolle, welche Einstellungen der Benutzer hat oder was die zugrunde liegenden regionalen Einstellungen sind, Ihre Daten werden immer so interpretiert, wie sie beabsichtigt waren. Wenn Sie derzeit Benutzern erlauben, Daten in ein Textfeld eines Formulars einzugeben, hören Sie damit auf und implementieren Sie ein Kalendersteuerelement oder zumindest eine Auswahlliste, damit Sie letztendlich das Zeichenfolgenformat steuern können, das an SQL Server zurückgegeben wird.

Für etwas Hintergrund lesen Sie bitte Tibor Karaszis "The ultimative guide to the datetime Datentypen" und mein Beitrag "Bad Gewohnheiten zu treten:Misshandlung von Datums-/Bereichsabfragen."