Het kan gemakkelijk zijn om te vergeten dat de T-SQL FORMAT()
functie biedt locale-bewuste opmaak. Locale-aware betekent dat de locale de resultaten kan beïnvloeden. Met andere woorden, de exacte uitvoer die u krijgt, is afhankelijk van de landinstelling.
Standaard gebruikt de functie de taal van de huidige sessie om de landinstelling te bepalen. Dit kan echter worden overschreven door een "cultuur" -argument door te geven aan de functie. Als u dit doet, kunt u resultaten leveren voor een bepaalde landinstelling zonder dat u de taal van de huidige sessie hoeft te wijzigen.
Dit artikel bevat voorbeelden van hoe de landinstelling de resultaten kan beïnvloeden bij gebruik van de FORMAT()
functie in SQL Server.
Voorbeeld 1 – Valuta's
Hier is een snel voorbeeld om te laten zien hoe taal/cultuur uw resultaten kan beïnvloeden bij het opmaken van getallen.
DECLARE @num decimal(6,2) = 1234.56; SELECT FORMAT(@num, 'C', 'en-us') 'en-us', FORMAT(@num, 'C', 'en-gb') 'en-gb', FORMAT(@num, 'C', 'th-th') 'th-th', FORMAT(@num, 'C', 'nl-nl') 'nl-nl', FORMAT(@num, 'C', 'ne-np') 'ne-np', FORMAT(@num, 'C', 'fa-ir') 'fa-ir';
Resultaten:
+-----------+-----------+-----------+------------+------------+--------------+ | en-us | en-gb | th-th | nl-nl | ne-np | fa-ir | |-----------+-----------+-----------+------------+------------+--------------| | $1,234.56 | £1,234.56 | ฿1,234.56 | € 1.234,56 | रु 1,234.56 | 1,234/56ريال | +-----------+-----------+-----------+------------+------------+--------------+
De C
in dit voorbeeld is een standaard numerieke notatiespecificatie. Dit enkele teken geeft aan dat de waarde op een bepaalde manier moet worden opgemaakt (in dit geval als valuta). Gelukkig is SQL Server slim genoeg om te weten dat niet alle culturen hetzelfde formaat gebruiken en dat het automatisch een ander formaat presenteert, afhankelijk van de cultuur.
In het bovenstaande voorbeeld, elke keer dat ik FORMAT()
. aanroep , geef ik dezelfde waarde en opmaakreeks door. Het enige verschil is de waarde van het cultuurargument. Dit zorgt ervoor dat de resultaten verschillend zijn, afhankelijk van de cultuur die wordt gebruikt. Het valutasymbool en de positionering ervan wordt bepaald door de cultuur. Het teken dat wordt gebruikt voor decimaaltekens en groepsscheidingstekens wordt ook bepaald door de cultuur.
Voorbeeld 2 – Negatieve waarden
De opmaak kan ook afhangen van het feit of de waarde positief of negatief is. Als we een negatieve waarde gebruiken, gebeurt het volgende:
DECLARE @num decimal(3,2) = -1.23; SELECT FORMAT(@num, 'C', 'en-us') 'en-us', FORMAT(@num, 'C', 'en-gb') 'en-gb', FORMAT(@num, 'C', 'th-th') 'th-th', FORMAT(@num, 'C', 'nl-nl') 'nl-nl', FORMAT(@num, 'C', 'ne-np') 'ne-np', FORMAT(@num, 'C', 'fa-ir') 'fa-ir';
Resultaten:
+---------+---------+---------+---------+---------+-----------+ | en-us | en-gb | th-th | nl-nl | ne-np | fa-ir | |---------+---------+---------+---------+---------+-----------| | ($1.23) | -£1.23 | -฿1.23 | € -1,23 | -रु 1.23 | 1/23-ريال | +---------+---------+---------+---------+---------+-----------+
In sommige culturen verschijnt het minteken vóór het valutateken, in andere culturen erna. Maar in andere culturen is er helemaal geen minteken - het is vervangen door haakjes die het hele resultaat omringen, inclusief het valutateken.
We moeten er echter niet van uitgaan dat dezelfde regels worden toegepast op alle opmaakreeksen. Als we het bijvoorbeeld opmaken als een getal in plaats van een valuta, krijgen we geen haakjes:
DECLARE @num decimal(3,2) = -1.23; SELECT FORMAT(@num, 'N', 'en-us') 'en-us', FORMAT(@num, 'N', 'en-gb') 'en-gb', FORMAT(@num, 'N', 'th-th') 'th-th', FORMAT(@num, 'N', 'nl-nl') 'nl-nl', FORMAT(@num, 'N', 'ne-np') 'ne-np', FORMAT(@num, 'N', 'fa-ir') 'fa-ir';
Resultaten:
+---------+---------+---------+---------+---------+---------+ | en-us | en-gb | th-th | nl-nl | ne-np | fa-ir | |---------+---------+---------+---------+---------+---------| | -1.23 | -1.23 | -1.23 | -1,23 | -1.23 | 1/23- | +---------+---------+---------+---------+---------+---------+
Voorbeeld 3 – Datums en tijden
Nummeropmaak is niet het enige dat wordt beïnvloed door cultuur. Datums en tijden zullen bijvoorbeeld ook anders worden opgemaakt, afhankelijk van de cultuur.
DECLARE @date datetime2(0) = '2019-06-15 13:45:30'; SELECT FORMAT(@date, 'G', 'en-us') 'en-us', FORMAT(@date, 'G', 'en-gb') 'en-gb', FORMAT(@date, 'G', 'th-th') 'th-th', FORMAT(@date, 'G', 'nl-nl') 'nl-nl', FORMAT(@date, 'G', 'ne-np') 'ne-np', FORMAT(@date, 'G', 'fa-ir') 'fa-ir';
Resultaten (met verticale uitvoer):
en-us | 6/15/2019 1:45:30 PM en-gb | 15/06/2019 13:45:30 th-th | 15/6/2562 13:45:30 nl-nl | 15-6-2019 13:45:30 ne-np | 6/15/2019 1:45:30 अपराह्न fa-ir | 25/03/1398 01:45:30 ب.ظ
Dit voorbeeld gebruikt een algemene datum/lange tijdnotatie (bereikt door gebruik te maken van G
– een van de standaardspecificaties voor datum- en tijdformaat), en de verschillen tussen culturen zijn duidelijk.
Maar we kunnen ook verschillen zien, zelfs bij gebruik van een lange datumnotatie:
DECLARE @date datetime2(0) = '2019-06-15 13:45:30'; SELECT FORMAT(@date, 'F', 'en-us') 'en-us', FORMAT(@date, 'F', 'en-gb') 'en-gb', FORMAT(@date, 'F', 'th-th') 'th-th', FORMAT(@date, 'F', 'nl-nl') 'nl-nl', FORMAT(@date, 'F', 'ne-np') 'ne-np', FORMAT(@date, 'F', 'fa-ir') 'fa-ir';
Resultaten (met verticale uitvoer):
en-us | Saturday, June 15, 2019 1:45:30 PM en-gb | 15 June 2019 13:45:30 th-th | 15 มิถุนายน 2562 13:45:30 nl-nl | zaterdag 15 juni 2019 13:45:30 ne-np | शनिवार, जून 15, 2019 1:45:30 अपराह्न fa-ir | شنبه, 25 خرداد 1398 01:45:30 ب.ظ
Voorbeeld 4 – Hoe zit het met aangepaste opmaakstrings?
De vorige voorbeelden gebruiken strings met standaardopmaak, die vrijwel de opmaak voor u doen. Het is als een verkorte manier om een aangepaste opmaakreeks op te geven. Met een aangepaste indelingsspecificatie daarentegen kunt u precies specificeren welke tekens in de uitvoer worden weergegeven en waar ze naartoe gaan. Dit betekent echter meestal dat u meer opmaakspecificaties in uw opmaaktekenreeks moet gebruiken.
Maar zelfs wanneer u aangepaste formaatspecificaties gebruikt, kan de exacte uitvoer ook afhankelijk zijn van de landinstelling. Als we een aangepaste tekenreeks voor datum- en tijdnotatie wilden gebruiken om het vorige voorbeeld na te bootsen, zouden we zoiets als dit kunnen doen:
DECLARE @date datetime2(0) = '2019-06-15 13:45:30'; SELECT FORMAT(@date, 'dddd, dd MMMM yyyy hh:mm:ss tt', 'en-us') 'en-us', FORMAT(@date, 'dddd, dd MMMM yyyy hh:mm:ss tt', 'en-gb') 'en-gb', FORMAT(@date, 'dddd, dd MMMM yyyy hh:mm:ss tt', 'th-th') 'th-th', FORMAT(@date, 'dddd, dd MMMM yyyy hh:mm:ss tt', 'nl-nl') 'nl-nl', FORMAT(@date, 'dddd, dd MMMM yyyy hh:mm:ss tt', 'ne-np') 'ne-np', FORMAT(@date, 'dddd, dd MMMM yyyy hh:mm:ss tt', 'fa-ir') 'fa-ir';
Resultaten (met verticale uitvoer):
en-us | Saturday, 15 June 2019 01:45:30 PM en-gb | Saturday, 15 June 2019 01:45:30 PM th-th | เสาร์, 15 มิถุนายน 2562 01:45:30 PM nl-nl | zaterdag, 15 juni 2019 01:45:30 ne-np | शनिवार, 15 जून 2019 01:45:30 अपराह्न fa-ir | شنبه, 25 خرداد 1398 01:45:30 ب.ظ
Waarschijnlijk de meest voor de hand liggende observatie is dat het resultaat is opgemaakt in de taal van de opgegeven landinstelling. Maar als we goed kijken, kunnen we zien dat het ook de AM/PM-aanduiding negeert (tt
) voor de nl-nl
cultuur, waarschijnlijk omdat die cultuur doorgaans de 24-uursklok gebruikt. We kunnen ook zien dat zelfs onze positionering in sommige gevallen kan worden genegeerd (bijv. fa-ir
).
Niet alles wordt echter genegeerd en dus eindigen we met een combinatie van onze expliciete specificaties en die bepaald door de locale.
Uw huidige taal zoeken/wijzigen
Zoals gezegd, als u het argument "cultuur" niet opgeeft, wordt de taal van uw huidige sessie gebruikt om de landinstelling te bepalen.
Er zijn verschillende manieren om de taal van uw huidige sessie te vinden.
U kunt ook de landinstelling van uw huidige verbinding wijzigen.
U kunt ook gewoon de SET LANGUAGE
. gebruiken statement om de huidige taal naar wens te wijzigen.
Hier is een snel voorbeeld van het gebruik van SET LANGUAGE
om aan te tonen dat uw eigen taalinstellingen de opmaakresultaten net zo kunnen beïnvloeden als wanneer u het argument 'cultuur' gebruikt, zoals in de vorige voorbeelden.
DECLARE @num decimal(3,2) = -1.23; SET LANGUAGE British; SELECT FORMAT(@num, 'C') Result; SET LANGUAGE US_English; SELECT FORMAT(@num, 'C') Result;
Resultaten:
+----------+ | Result | |----------| | -£1.23 | +----------+ +----------+ | Result | |----------| | ($1.23) | +----------+