T-SQLのFORMAT()
を忘れがちです。 関数はロケール対応のフォーマットを提供します。ロケール対応とは、ロケールが結果に影響を与える可能性があることを意味します。つまり、取得する正確な出力はロケールによって異なります。
デフォルトでは、関数は現在のセッションの言語を使用してロケールを決定します。ただし、これは、関数に「カルチャ」引数を渡すことでオーバーライドできます。これにより、現在のセッションの言語を変更することなく、特定のロケールの結果を提供できます。
この記事には、FORMAT()
を使用したときにロケールが結果にどのように影響するかについての例が含まれています SQLServerで機能します。
例1-通貨
これは、言語/文化が数値をフォーマットするときに結果にどのように影響するかを示す簡単な例です。
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';
結果:
+-----------+-----------+-----------+------------+------------+--------------+ | 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ريال | +-----------+-----------+-----------+------------+------------+--------------+
C
この例では、標準の数値形式指定子です。この1文字は、値を特定の方法(この場合は通貨)でフォーマットする必要があることを指定します。幸い、SQL Serverは、すべてのカルチャが同じ形式を使用しているわけではなく、カルチャに応じて自動的に異なる形式を表示することを認識できるほど賢いです。
上記の例では、FORMAT()
を呼び出すたびに 、同じ値とフォーマット文字列を渡します。唯一の違いは、カルチャ引数の値です。これにより、使用するカルチャによって結果が異なります。通貨記号とその位置は、文化によって決まります。小数点とグループの区切り文字に使用される文字も、カルチャによって決定されます。
例2–負の値
フォーマットは、値が正か負かによっても異なります。負の値を使用すると、次のようになります。
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';
結果:
+---------+---------+---------+---------+---------+-----------+ | en-us | en-gb | th-th | nl-nl | ne-np | fa-ir | |---------+---------+---------+---------+---------+-----------| | ($1.23) | -£1.23 | -฿1.23 | € -1,23 | -रु 1.23 | 1/23-ريال | +---------+---------+---------+---------+---------+-----------+
一部の文化では、マイナス記号は通貨記号の前に表示され、他の文化では通貨記号の後に表示されます。ただし、他のカルチャでは、マイナス記号はまったくありません。通貨記号を含む結果全体を囲む括弧に置き換えられます。
ただし、すべてのフォーマット文字列に同じルールが適用されると想定するべきではありません。たとえば、通貨ではなく数値としてフォーマットした場合、括弧はありません:
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';
結果:
+---------+---------+---------+---------+---------+---------+ | en-us | en-gb | th-th | nl-nl | ne-np | fa-ir | |---------+---------+---------+---------+---------+---------| | -1.23 | -1.23 | -1.23 | -1,23 | -1.23 | 1/23- | +---------+---------+---------+---------+---------+---------+
例3–日付と時刻
文化の影響を受けるのは数字の書式設定だけではありません。たとえば、日付と時刻も文化によって異なる形式になります。
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';
結果(垂直出力を使用):
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 ب.ظ
この例では、一般的な日付/長い時間の形式を使用しています(G
を使用して実現) –標準の日付と時刻の形式指定子の1つ)、およびカルチャ間の違いは明らかです。
ただし、長い日付形式を使用している場合でも違いがわかります。
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';
結果(垂直出力を使用):
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 ب.ظ
例4–カスタムフォーマット文字列はどうですか?
前の例では、標準のフォーマット文字列を使用しています。これにより、フォーマットがほぼ実行されます。これは、カスタム形式の文字列を指定する簡単な方法のようなものです。一方、カスタムフォーマット指定子を使用すると、出力に表示される文字とその配置先を正確に指定できます。ただし、これは通常、フォーマット文字列でより多くのフォーマット指定子を使用する必要があることを意味します。
ただし、カスタム形式指定子を使用する場合でも、正確な出力はロケールによっても異なります。前の例を模倣するためにカスタムの日付と時刻の形式の文字列を使用する場合は、次のようにします。
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';
結果(垂直出力を使用):
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 ب.ظ
おそらく最も明白な観察は、結果が指定されたロケールの言語を使用してフォーマットされていることです。しかし、よく見ると、AM / PM指定子(tt
)も無視していることがわかります。 )nl-nl
の場合 おそらくその文化は通常24時間制を使用しているためです。また、場合によっては、ポジショニングさえ無視できることがわかります(例:fa-ir
)。
ただし、すべてが無視されるわけではないため、明示的な仕様とロケールによって決定された仕様の組み合わせになります。
現在の言語の検索/変更
前述のように、「カルチャ」引数を指定しない場合、現在のセッションの言語がロケールの決定に使用されます。
現在のセッションの言語を見つける方法はいくつかあります。
現在の接続のロケールを変更することもできます。
または、SET LANGUAGE
を使用することもできます 必要に応じて現在の言語を切り替えるステートメント。
SET LANGUAGE
を使用した簡単な例を次に示します。 前の例のように、「カルチャ」引数を使用する場合とまったく同じように、独自の言語設定がフォーマット結果に影響を与える可能性があることを示します。
DECLARE @num decimal(3,2) = -1.23; SET LANGUAGE British; SELECT FORMAT(@num, 'C') Result; SET LANGUAGE US_English; SELECT FORMAT(@num, 'C') Result;
結果:
+----------+ | Result | |----------| | -£1.23 | +----------+ +----------+ | Result | |----------| | ($1.23) | +----------+