sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo la configuración de idioma puede afectar sus resultados de FORMAT() en SQL Server (ejemplos de T-SQL)

Puede ser fácil olvidar que T-SQL FORMAT() La función proporciona un formato compatible con la configuración regional. Consciente de la configuración regional significa que la configuración regional puede afectar los resultados. En otras palabras, el resultado exacto que obtenga dependerá de la configuración regional.

De forma predeterminada, la función utiliza el idioma de la sesión actual para determinar la configuración regional. Sin embargo, esto se puede anular pasando un argumento de "cultura" a la función. Hacer esto le permite proporcionar resultados para una configuración regional en particular sin tener que cambiar el idioma de la sesión actual.

Este artículo contiene ejemplos de cómo la configuración regional puede afectar los resultados cuando se usa FORMAT() función en SQL Server.

Ejemplo 1:Monedas

Aquí hay un ejemplo rápido para demostrar cómo el idioma o la cultura pueden afectar sus resultados al dar formato a los números.

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

Resultados:

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

El C en este ejemplo es un especificador de formato numérico estándar. Este carácter único especifica que el valor debe tener un formato determinado (en este caso, como moneda). Afortunadamente, SQL Server es lo suficientemente inteligente como para saber que no todas las culturas usan el mismo formato y presenta automáticamente un formato diferente según la cultura.

En el ejemplo anterior, cada vez que llamo a FORMAT() , paso el mismo valor y cadena de formato. La única diferencia es el valor del argumento cultural. Esto hace que los resultados sean diferentes, según el cultivo que se utilice. El símbolo de la moneda y su posicionamiento están determinados por la cultura. El carácter utilizado para los separadores decimales y los separadores de grupo también está determinado por la referencia cultural.

Ejemplo 2:valores negativos

El formato también puede depender de si el valor es positivo o negativo. Si usamos un valor negativo, esto es lo que sucede:

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

Resultados:

+---------+---------+---------+---------+---------+-----------+
| en-us   | en-gb   | th-th   | nl-nl   | ne-np   | fa-ir     |
|---------+---------+---------+---------+---------+-----------|
| ($1.23) | -£1.23  | -฿1.23  | € -1,23 | -रु 1.23 | 1/23-ريال    |
+---------+---------+---------+---------+---------+-----------+

En algunas culturas, el signo menos aparece antes del signo de moneda, en otras aparece después. Pero en otras culturas, no hay ningún signo menos:se reemplaza con paréntesis que rodean todo el resultado, incluido el signo de moneda.

Sin embargo, no debemos asumir que se aplican las mismas reglas en todas las cadenas de formato. Por ejemplo, si lo formateamos como un número en lugar de una moneda, no obtenemos ningún paréntesis:

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

Resultados:

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

Ejemplo 3:fechas y horas

El formato de los números no es lo único que se ve afectado por la cultura. Las fechas y horas, por ejemplo, también tendrán un formato diferente según la 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';

Resultados (usando salida vertical):

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

Este ejemplo usa un formato general de fecha/tiempo prolongado (logrado usando G – uno de los especificadores de formato de fecha y hora estándar), y las diferencias entre culturas son obvias.

Pero también podemos ver diferencias incluso cuando usamos un formato de fecha larga:

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

Resultados (usando salida vertical):

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

Ejemplo 4:¿Qué pasa con las cadenas de formato personalizado?

Los ejemplos anteriores usan cadenas de formato estándar, que prácticamente hacen el formato por usted. Es como una forma abreviada de especificar una cadena de formato personalizado. Un especificador de formato personalizado, por otro lado, le permite especificar exactamente qué caracteres aparecen en la salida y adónde van. Sin embargo, esto generalmente significa que necesita usar más especificadores de formato en su cadena de formato.

Pero incluso cuando usa especificadores de formato personalizados, la salida exacta también puede depender de la configuración regional. Si quisiéramos usar una cadena de formato de fecha y hora personalizada para imitar el ejemplo anterior, podríamos hacer algo como esto:

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

Resultados (usando salida vertical):

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

Probablemente la observación más obvia es que el resultado se formatea utilizando el idioma de la configuración regional especificada. Pero si miramos de cerca, podemos ver que también ignora el designador AM/PM (tt ) para el nl-nl probablemente porque esa cultura normalmente usa el reloj de 24 horas. También podemos ver que incluso nuestro posicionamiento puede ignorarse en algunos casos (por ejemplo, fa-ir ).

Sin embargo, no todo se ignora, por lo que terminamos con una combinación de nuestras especificaciones explícitas y las determinadas por la configuración regional.

Encontrar/cambiar su idioma actual

Como se mencionó, si no proporciona el argumento de "cultura", se usará el idioma de su sesión actual para determinar la configuración regional.

Hay varias formas de encontrar el idioma de su sesión actual.

También puede cambiar la configuración regional de su conexión actual.

Alternativamente, puede usar el SET LANGUAGE instrucción para cambiar el idioma actual según sea necesario.

Aquí hay un ejemplo rápido usando SET LANGUAGE para mostrar que su propia configuración de idioma puede afectar los resultados de formato de la misma manera que cuando usa el argumento "cultura", como en los ejemplos anteriores.

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

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

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

Resultados:

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

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