Nicht deterministische Konvertierung von Datumsliteralen in DATE-Werte

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

Seien Sie vorsichtig, wenn Sie die Konvertierung Ihrer CHARACTER-Zeichenfolgen in DATE-Datentypen zulassen. Der Grund dafür ist, dass solche Konvertierungen oft nicht deterministisch sind.

Sie steuern diese nicht deterministischen Konvertierungen, indem Sie die Einstellungen von SET LANGUAGE und SET DATEFORMAT berücksichtigen.

Beispiel für SET LANGUAGE: Monatsname in polnischer Sprache

  • SET LANGUAGE Polish;

Eine Zeichenfolge kann der Name eines Monats sein. Aber ist der Name in englischer, polnischer, kroatischer oder einer anderen Sprache? Und wird die Sitzung des Benutzers auf die richtige entsprechende SPRACHE festgelegt?

Nehmen Sie z. B. das Wort listopad, das der Name eines Monats ist. Aber welcher Monat es ist, hängt von der Sprache ab, von der das SQL Server-System glaubt, dass sie verwendet wird:

  • Falls Polnisch, steht listopad für den 11. Monat (November auf Englisch).
  • Falls Kroatisch, steht listopad für den 10. Monat (Oktober auf Englisch).

Codebeispiel für SET LANGUAGE

--SELECT alias FROM sys.syslanguages ORDER BY alias;

DECLARE @yourInputDate  NVARCHAR(32) = '28 listopad 2018';

SET LANGUAGE Polish;
SELECT CONVERT(DATE, @yourInputDate) AS [SL_Polish];

SET LANGUAGE Croatian;
SELECT CONVERT(DATE, @yourInputDate) AS [SL_Croatian];

SET LANGUAGE English;


/***  Actual output:  For the two months, note the 11 versus the 10.
SL_Polish
2018-11-28

SL_Croatian
2018-10-28
***/

Beispiel für SET DATEFORMAT

  • SET DATEFORMAT dmy;

Das voranstehende dmy-Format besagt, dass z. B. die Datumszeichenfolge '01-03-2018' so interpretiert wird, dass sie den ersten Tag im März im Jahr 2018 bedeutet.

Wenn stattdessen mdy angegeben wird, würde die gleiche Zeichenfolge '01-03-2018' den dritten Tag im Januar 2018 bedeuten.

Und wenn ymd angegeben würde, gibt es keine Garantie dafür, wie die Ausgabe aussehen würde. Der numerische Wert '2018' ist zu groß für einen Tag.

Bestimmte Länder/Regionen

In Japan und China wird das DATEFORMAT ymd verwendet. Die Teile des Formats befinden sich in einer sinnvollen Reihenfolge von der größten Einheit zur kleinsten. Somit lässt sich dieses Format gut sortieren. Dieses Format gilt als internationales Format. Es ist international, weil die vier Ziffern des Jahres eindeutig sind und kein Land/keine Region der Erde das archaische Format ydm verwendet.

In anderen Ländern/Regionen wie Deutschland und Frankreich ist das DATEFORMAT dmy, was 'TT.MM.JJJJ' bedeutet. Das dmy-Format lässt sich nicht gut sortieren, aber es ist eine sinnvolle Reihenfolge von der kleinsten bis zur größten Einheit.

Die USA und die Föderierten Staaten von Mikronesien sind die einzigen Länder/Regionen, die mdy verwenden, was sich nicht sortieren lässt. Die gemischte Reihenfolge des Formats entspricht einem Muster mündlicher Sprache in gesprochenen Datumsangaben.

Codebeispiel für die SET DATEFORMAT: mdy im Vergleich zu dmy

Das folgende Transact-SQL-Codebeispiel verwendet die gleiche Datumszeichenfolge mit drei unterschiedlichen DATEFORMAT-Einstellungen. Bei Ausführung des Codes wird die im Kommentar gezeigte Ausgabe generiert:

DECLARE @yourDateString NVARCHAR(10) = '12-09-2018';
PRINT @yourDateString + '  = the input.';

SET DATEFORMAT dmy;
SELECT CONVERT(DATE, @yourDateString) AS [DMY-Interpretation-of-input-format];

SET DATEFORMAT mdy;
SELECT CONVERT(DATE, @yourDateString) AS [MDY-Interpretation-of-input-format];

SET DATEFORMAT ymd;
SELECT CONVERT(DATE, @yourDateString) AS [YMD-Interpretation--?--NotGuaranteed];


/***  Actual output:
12-09-2018  = the input.

DMY-Interpretation-of-input-format
2018-09-12

MDY-Interpretation-of-input-format
2018-12-09

YMD-Interpretation--?--NotGuaranteed
2018-12-09
***/

Im vorhergehenden Codebeispiel weist das letzte Beispiel eine Nichtübereinstimmung zwischen dem Format ymd und der Eingabezeichenfolge auf. Der dritte Knoten der Eingabezeichenfolge stellt einen Zahlenwert dar, der für einen Tag zu groß ist. Bei solchen Nichtübereinstimmungen garantiert Microsoft nicht den Ausgabewert.

CONVERT bietet explizite Codes für die deterministische Steuerung von Datumsformaten.

Unser Dokumentationsartikel zu CAST und CONVERT enthält explizite Codes, die Sie mit der CONVERT-Funktion verwenden können, um Datumskonvertierungen deterministisch zu steuern. Jeden Monat hat der Artikel eine der höchsten Zugriffszahlen.

Kompatibilitätsgrad 90 und höher

Bei SQL Server 2000 war der Kompatibilitätsgrad 80. Für Gradeinstellungen von 80 oder niedriger waren implizite Datumskonvertierungen deterministisch.

Ab SQL Server 2005 und dessen Kompatibilitätsgrad 90 wurden implizite Datumskonvertierungen nicht mehr deterministisch. Ab Grad 90 wurden die Datumskonvertierungen von SET LANGUAGE und SET DATEFORMAT abhängig.

Unicode

Die Konvertierung von Nicht-Unicode-Zeichendaten zwischen Sortierungen wird auch als nicht deterministisch angesehen.

Weitere Informationen