Icke-deterministisk konvertering av bokstavliga datumsträngar till DATE-värden

gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

Var försiktig när du tillåter konvertering av dina CHARACTER-strängar till DATE-datatyper. Anledningen är att sådana konverteringar ofta är icke-deterministiska.

Du styr dessa icke-deterministiska omvandlingar genom att ta hänsyn till inställningarna för SET LANGUAGE och SET DATEFORMAT.

SET LANGUAGE exempel: Månadsnamn på polska

  • SET LANGUAGE Polish;

En teckensträng kan vara namnet på en månad. Men är namnet på engelska, polska, kroatiska eller på ett annat språk? Och kommer användarens session att ställas in till rätt motsvarande LANGUAGE?

Tänk till exempel på ordet listopad, som är namnet på en månad. Men vilken månad det är beror på vilket språk SQL-systemet tror används:

  • Om det är polskt betyder listopad månad 11 (november på engelska).
  • Om det är kroatiskt, så översätts listopad till månad 10 (oktober på engelska).

Kodexempel på 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 exempel

  • SET DATEFORMAT dmy;

Det föregående dmy-formatet säger att ett exempel på datumsträngen '01-03-2018' skulle tolkas som första mars år 2018.

Om mdy istället specificerades, skulle samma '01-03-2018'-sträng betyda tredje januari 2018.

Och om YMD specificerades finns det ingen garanti för vad resultatet skulle bli. Det numeriska värdet av '2018' är för stort för att vara en dag.

Specifika länder/regioner

I Japan och Kina används betydelsen DATEFORMATymd . Formatets delar är i en rimlig ordning från största till minsta enhet. Så det här formatet fungerar bra. Detta format anses vara det internationella formatet. Det är internationellt eftersom årets fyra siffror är entydiga och inget land/region på jorden använder det arkaiska ydm-formatet.

I andra länder/regioner som Tyskland och Frankrike är det DATEFORMATdmy, vilket betyder 'dd-mm-yyyy'. Dmy-formatet sorterar inte så bra, men det är en vettig sekvens från minsta enhet till största.

United States och Federated States of Micronesia är de enda länderna/regionerna som använder MDY, som inte sorterar. Formatets blandade sekvens följer ett mönster av muntligt tal i talade träffar.

Kodexempel på SET DATEFORMAT: mdy mot dmy

Följande Transact-SQL kodexempel använder samma datumstav med tre olika DATEFORMAT inställningar. En körning av koden ger det utdata som visas i kommentaren:

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

I föregående kodexempel har det sista exemplet en mismatch mellan format ymd och indatasträngen. Den tredje noden i indatasträngen representerar ett numeriskt värde som är för stort för att vara en dag. Microsoft garanterar inte utgångsvärdet från sådana omatchningar.

CONVERT erbjuder explicita koder för deterministisk kontroll av datumformat

Vår dokumentationsartikel CAST and CONVERT listar explicita koder som du kan använda med CONVERT-funktionen för att deterministiskt kontrollera datumkonverteringar. Varje månad har artikeln en av våra högsta sidvisningar.

Kompatibilitetsnivå 90 och högre

I SQL Server 2000 var kompatibilitetsnivån 80. För nivåinställningar på 80 eller lägre var implicita datumkonverteringar deterministiska.

Från och med SQL Server 2005 och dess kompatibilitetsnivå på 90 blev implicita datumkonverteringar icke-deterministiska. Datumkonverteringar blev beroende av SETSET LANGUAGE och SETSET DATEFORMAT började med nivå 90.

Unicode

Konvertering av icke-Unicode-teckendata mellan sorteringar anses också vara icke-deterministisk.

Se även