Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

In che modo le impostazioni della lingua possono influire sui risultati di FORMAT() in SQL Server (esempi T-SQL)

Può essere facile dimenticare che il T-SQL FORMAT() la funzione fornisce una formattazione in grado di riconoscere le impostazioni locali. Locale-aware significa che le impostazioni locali possono influenzare i risultati. In altre parole, l'output esatto che otterrai dipenderà dalla locale.

Per impostazione predefinita, la funzione utilizza la lingua della sessione corrente per determinare la locale. Tuttavia, questo può essere ignorato passando un argomento "cultura" alla funzione. In questo modo puoi fornire risultati per una determinata locale senza dover cambiare la lingua della sessione corrente.

Questo articolo contiene esempi di come le impostazioni locali possono influenzare i risultati quando si utilizza FORMAT() funzione in SQL Server.

Esempio 1 – Valute

Ecco un rapido esempio per dimostrare in che modo lingua/cultura possono influenzare i risultati durante la formattazione dei numeri.

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';

Risultati:

+-----------+-----------+-----------+------------+------------+--------------+
| 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ريال    |
+-----------+-----------+-----------+------------+------------+--------------+

Il C in questo esempio è un identificatore di formato numerico standard. Questo singolo carattere specifica che il valore deve essere formattato in un certo modo (in questo caso, come valuta). Fortunatamente, SQL Server è abbastanza intelligente da sapere che non tutte le impostazioni cultura utilizzano lo stesso formato e presenta automaticamente un formato diverso a seconda delle impostazioni cultura.

Nell'esempio sopra, ogni volta che chiamo FORMAT() , passo lo stesso valore e formatta la stringa. L'unica differenza è il valore dell'argomento cultura. Ciò fa sì che i risultati siano diversi, a seconda della cultura utilizzata. Il simbolo della valuta e il suo posizionamento sono determinati dalla cultura. Il carattere utilizzato per i separatori decimali e di gruppo è determinato anche dalle impostazioni cultura.

Esempio 2 – Valori negativi

La formattazione può anche dipendere dal fatto che il valore sia positivo o negativo. Se utilizziamo un valore negativo, ecco cosa succede:

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';

Risultati:

+---------+---------+---------+---------+---------+-----------+
| 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 alcune culture, il segno meno appare prima del segno di valuta, in altre appare dopo di esso. Ma in altre culture, non c'è alcun segno meno:è sostituito da parentesi che circondano l'intero risultato, incluso il segno di valuta.

Tuttavia, non dobbiamo presumere che le stesse regole vengano applicate a tutte le stringhe di formato. Ad esempio, se lo formattiamo come numero anziché come valuta, non otteniamo parentesi:

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';

Risultati:

+---------+---------+---------+---------+---------+---------+
| en-us   | en-gb   | th-th   | nl-nl   | ne-np   | fa-ir   |
|---------+---------+---------+---------+---------+---------|
| -1.23   | -1.23   | -1.23   | -1,23   | -1.23   | 1/23-   |
+---------+---------+---------+---------+---------+---------+

Esempio 3 – Date e orari

La formattazione dei numeri non è l'unica cosa che è influenzata dalla cultura. Anche le date e gli orari, ad esempio, verranno formattati in modo diverso a seconda della cultura.

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';

Risultati (usando l'output verticale):

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 ب.ظ

Questo esempio utilizza un formato generale di data/ora (ottenuto utilizzando G – uno degli identificatori di formato di data e ora standard) e le differenze tra le culture sono evidenti.

Ma possiamo anche vedere differenze anche quando si utilizza un formato di data lungo:

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';

Risultati (usando l'output verticale):

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 ب.ظ

Esempio 4 – Che dire delle stringhe di formato personalizzato?

Gli esempi precedenti utilizzano stringhe di formato standard, che eseguono praticamente la formattazione per te. È come un modo abbreviato per specificare una stringa di formato personalizzata. Un identificatore di formato personalizzato, d'altra parte, ti consente di specificare esattamente quali caratteri appaiono nell'output e dove vanno. Tuttavia, questo in genere significa che è necessario utilizzare più identificatori di formato nella stringa di formato.

Ma anche quando si utilizzano identificatori di formato personalizzati, l'output esatto può dipendere anche dalle impostazioni locali. Se volessimo utilizzare una stringa di formato data e ora personalizzata per imitare l'esempio precedente, potremmo fare qualcosa del genere:

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';

Risultati (usando l'output verticale):

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 ب.ظ

Probabilmente l'osservazione più ovvia è che il risultato è formattato utilizzando la lingua della locale specificata. Ma se osserviamo da vicino, possiamo vedere che ignora anche il designatore AM/PM (tt ) per il nl-nl cultura, probabilmente perché quella cultura utilizza tipicamente l'orologio a 24 ore. Possiamo anche vedere che anche il nostro posizionamento può essere ignorato in alcuni casi (es. fa-ir ).

Tuttavia, non tutto viene ignorato e quindi ci ritroviamo con una combinazione delle nostre specifiche esplicite e quelle determinate dalla locale.

Trovare/Cambiare la lingua corrente

Come accennato, se non fornisci l'argomento "cultura", la lingua della tua sessione corrente verrà utilizzata per determinare la locale.

Esistono diversi modi per trovare la lingua della sessione corrente.

Puoi anche cambiare la lingua della tua connessione attuale.

In alternativa, puoi semplicemente utilizzare il SET LANGUAGE dichiarazione per cambiare la lingua corrente come richiesto.

Ecco un rapido esempio utilizzando SET LANGUAGE per mostrare che le impostazioni della tua lingua possono influenzare i risultati di formattazione proprio come quando usi l'argomento "cultura", come negli esempi precedenti.

DECLARE @num decimal(3,2) = -1.23;

SET LANGUAGE British;
SELECT FORMAT(@num, 'C') Result;

SET LANGUAGE US_English;
SELECT FORMAT(@num, 'C') Result;

Risultati:

+----------+
| Result   |
|----------|
| -£1.23   |
+----------+

+----------+
| Result   |
|----------|
| ($1.23)  |
+----------+