sql >> Databasteknik >  >> RDS >> Sqlserver

Hur använder man TimeZoneInfo i en SQLCLR-sammansättning i SQL Server 2012

Uppdaterat svar

Jag har skrivit verktyget jag talade om i det ursprungliga svaret, som du hittar här .

Från och med SQL Server 2016 (och Azure SQL Database) kan du nu använda AT TIME ZONE nyckelord för att konvertera mellan tidszoner.

Originalt svar

Tyvärr finns det ingen bra lösning för att arbeta med tidszoner i SQL Server.

Jag har undersökt problemet du länkade noggrant, tillsammans med denna också. Det finns inga inbyggda tidszonsfunktioner och all användning av TimeZoneInfo i SQLCLR kräver att sammansättningen är registrerad som "osäker". Detta är vanligtvis inte önskvärt.

Jag undersökte också med Noda Time från SQLCLR. Du kan läsa om det i det här numret . Det måste också registreras som "osäkert" på grund av hur vissa objekt cachelagras internt.

I slutändan, med båda objekten, är problemet att det inte finns något sätt att cachelagra något i SQLCLR. Du kan inte använda statiska variabler på ett trådsäkert sätt, och du kan inte göra någon trådsynkronisering eller använda klasser som ConcurrentDictionary . SQL vill ha full kontroll över gängningsmodellen för sammansättningen. Endast enkelgängad användning-en gång-och-släng-stilkod fungerar i "säkra" sammansättningar. Jag grävde djupt i detta i den här frågan:Multithreaded caching i SQL CLR

Förhoppningsvis kommer det så småningom vara en build av Noda Time som kommer att fungera i SQLCLR, men det kommer att vara en speciell build som inte gör någon cachning. Så det kommer inte att fungera lika snabbt, men det kommer att få jobbet gjort samtidigt som det är säkert.

TimeZoneInfo kommer sannolikt inte att förändras. Så om inte SQL Server-teamet någonsin tar med tidszonsfunktioner direkt till SQL Server på rätt sätt (som Oracle och Postgres gör), så har du bara några få alternativ:

  • Försök inte konvertera tidszoner i datalagret. Arbeta med datetime eller datetime2 värden i UTC, eller använd datetimeoffset värden med någon offset. Men gör alla konverteringar mellan tidszoner i applikationslagret. Detta är min bästa rekommendation för tillfället.

  • Kopiera all data för tidszonerna till faktiska SQL-tabeller och skriv funktioner som fungerar med dessa data. Detta är inte den bästa idén, eftersom data ändras ofta så tabellunderhåll kan vara en utmaning. Det kan också vara svårt att få funktionerna korrekta, inklusive alla regler för sommartidsändringar. Jag känner inte till något projekt som har det här snyggt och snyggt, men om någon är det - låt mig gärna veta i kommentarerna.

  • Aktivera xp_regread och arbeta med tidszonsdata direkt från Windows registernycklar. Uppdateringar skulle göras åt dig, men du har fortfarande samma utmaningar när du skriver dessa funktioner. Och att aktivera registerläsning kan vara en lika stor säkerhetsrisk som att aktivera osäkra CLR-sammansättningar ändå.

En annan idé jag funderar på är att skriva en IANA/Olson TZDB parser och funktioner specifikt för SQL Server. Detta skulle likna alternativ 2 ovan, men gjort på ett underhållbart sätt och med IANA standarddata istället för Windows tidszoner. Kanske kommer jag till det här någon gång, eller så kanske någon slår mig till det. Återigen, jag känner inte till något aktuellt projekt som gör detta, men om någon känner till ett, vänligen meddela mig i kommentarerna. (klar – se uppdatering högst upp )

Angående SWITCHOFFSET - det fungerar bara när du redan känner till målförskjutningen. Det är halva striden, och förmodligen därför Microsoft fortfarande markerar datetimeoffset som inte "sommartid medveten" i dokumenten .



  1. SQL kumulativt antal

  2. Jämföra Galera Cluster Cloud-erbjudanden:Del två Google Cloud Platform (GCP)

  3. Loop MySQL för att infoga data i tabellen

  4. Sammansatt primär nyckel kontra ytterligare ID-kolumn?