Niet-deterministische conversie van letterlijke datumreeksen naar DATUM-waarden

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

Wees voorzichtig bij het toestaan van conversie van je CHARACTER-strings naar DATE-datatypes. De reden hiervoor is dat dergelijke conversies vaak niet-deterministisch zijn.

Je beheerst deze niet-deterministische conversies door rekening te houden met de instellingen van SET LANGUAGE en SET DATEFORMAT.

SET LANGUAGE voorbeeld: Maandnaam in het Pools

  • SET LANGUAGE Polish;

Een tekenreeks kan de naam van een maand zijn. Maar is de naam in het Engels, of Pools, of Kroatisch, of in een andere taal? En wordt de sessie van de gebruiker ingesteld op de juiste overeenkomst LANGUAGE?

Neem bijvoorbeeld het woord listopad, wat de naam van een maand is. Maar in welke maand het is, hangt af van de taal waarvan het SQL-systeem denkt dat die wordt gebruikt:

  • Als je Pools bent, betekent listopad maand 11 (november in het Engels).
  • Als het Kroatisch is, betekent listopad maand 10 (oktober in het Engels).

Codevoorbeeld van 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
***/

SET DATEFORMAT voorbeeld

  • SET DATEFORMAT dmy;

Het voorgaande dmy-formaat zegt dat een voorbeeldreeks van '01-03-2018' zou worden geïnterpreteerd als de eerste dag van maart van het jaar 2018.

Als in plaats daarvan mdy werd gespecificeerd, zou dezelfde '01-03-2018'-string de derde dag van januari 2018 betekenen.

En als YMD is gespecificeerd, is er geen garantie voor wat de output zou zijn. De numerieke waarde van '2018' is te groot om een dag te zijn.

Specifieke landen/regio's

In Japan en China wordt de term DATEFORMATymd gebruikt. De onderdelen van het formaat zijn in een logische volgorde van grootste tot kleinste eenheid. Dus, dit format is goed te ordenen. Dit format wordt beschouwd als het internationale format. Het is internationaal omdat de vier cijfers van het jaar ondubbelzinnig zijn, en geen enkel land/regio op aarde het archaïsche format van ydm gebruikt.

In andere landen/regio's zoals Duitsland en Frankrijk is de DATEFORMATdmy, wat 'dd-mm-yyyy' betekent. Het dmy-formaat sorteert niet goed, maar het is een logische reeks van kleinste eenheid tot grootste.

De Verenigde Staten en de Federated States of Micronesia zijn de enige landen/regio's die MDY gebruiken, dat niet sorteert. De gemengde volgorde van het formaat komt overeen met een patroon van mondelinge spraak in gesproken data.

Codevoorbeeld van SET DATEFORMAT: mdy versus dmy

Het volgende Transact-SQL codevoorbeeld gebruikt dezelfde datumtekenreeks met drie verschillende DATEFORMAT instellingen. Een uitvoering van de code levert de output op die in de opmerking wordt getoond:

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

In het voorgaande codevoorbeeld heeft het laatste voorbeeld een mismatch tussen formaat ymd en de invoerstring. De derde knoop van de invoerstring vertegenwoordigt een numerieke waarde die te groot is om een dag te zijn. Microsoft garandeert de outputwaarde van zulke mismatches niet.

CONVERT biedt expliciete codes voor deterministische controle van datumformaten

Ons CAST and CONVERT-documentatieartikel vermeldt expliciete codes die je met de CONVERTE-functie kunt gebruiken om datumconversies deterministisch te regelen. Elke maand heeft het artikel een van onze hoogste paginaweergaven.

Compatibiliteitsniveau 90 en hoger

In SQL Server 2000 was het compatibiliteitsniveau 80. Voor niveau-instellingen van 80 of lager waren impliciete datumconversies deterministisch.

Vanaf SQL Server 2005 en het compatibiliteitsniveau van 90 werden impliciete datumconversies nondeterministisch. Datumconversies werden afhankelijk van SETSET LANGUAGE en SETSET DATEFORMAT vanaf niveau 90.

Unicode

De conversie van niet-Unicode-tekengegevens tussen collaties wordt ook als niet-deterministisch beschouwd.

Zie ook