助け合いフォーラム

Oracle DB

Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26836
問題を開く
次の実行結果となるSQL文として正しいものはどれですか。
ただし、実行環境は日本語環境とします。

 ¥500,000.0

正解

SELECT TO_CHAR(500000, 'L999G999D0') FROM dual;

SELECT TO_CHAR(500000.0, 'L999G999D0') FROM dual;

解説

TO_CHAR関数は数値を書式化した文字列に変換します。
設問では、数値を3桁ごとにカンマ(,)で区切り、小数点以下1桁を表示しています。カンマ(,)や小数点(.)は数値書式の中でそのまま用いることができますが、カンマは「G」、小数点は「D」で指定することもできます。なお、数値書式において、カンマを小数点の右側に指定することはできません。
また、¥記号を表示する場合は、ローカル通貨記号の「L」を指定します。

以上より、
・SELECT TO_CHAR(500000, 'L999G999D0') FROM dual;
・SELECT TO_CHAR(500000.0, 'L999G999D0') FROM dual;
が正解となります。

正解のSQL文の実行結果は次のようになります。





その他の選択肢については、以下のとおりです。

・SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual;
TO_NUMBER関数は、文字列を指定された書式にしたがって数値に変換します。変換された数値は¥やカンマを含むことは出来ないため、誤りです。



・SELECT TO_CHAR('¥500,000.0', 'L999G999D0') FROM dual;
TO_CHAR関数を使用していますが、第1引数には「¥」や「,」が含まれた文字列が指定されているため、エラーとなります。したがって、誤りです。



・SELECT TO_CHAR(500000, 'L999D999G0') FROM dual;
数値書式において、カンマ(G)を小数点(D)の右側に指定することはできないため、エラーとなります。したがって、誤りです。

参考

TO_CHAR関数は、数値や日付値を指定された書式に従って文字列に変換する関数です。
第1引数に数値が指定された場合は、数値を文字列へ変換します。
書式は以下の通りです。

 TO_CHAR(数値 [, '数値書式'] [, NLSパラメータ])

 
 

SQLを表示
SELECT TO_CHAR(1234.567, 'S99999.999')
FROM dual;


数値書式は数値を文字列に変換する際のフォーマットです。数値書式に使用できる主な要素は次のとおりです。



数値書式が省略された場合は、第1引数で指定された数値の有効桁数を保持するために十分な長さの文字列に変換されます。
NLSパラメータを指定すると、小数点文字、桁区切り文字、国際通貨記号、各国通貨記号を指定することができますが、省略された場合は、現在のセッションのデフォルトのパラメータ値が使用されます。

なお、第1引数で指定した数値(小数点より左の整数部)よりも数値書式の桁数が少ない場合など、数値を適切に変換できない場合は、次のように#記号が表示されます。


 
SQLを表示
SELECT TO_CHAR(commission, 'L999,999')
FROM employees;


第1引数で指定した数値の小数点以下は、数値書式の桁を超えていても四捨五入されて正常に表示されます。


また、第1引数の数値にマイナスの値が指定された場合は、数値書式に従って変換された文字列に-符号が適用されます。


 
SQLを表示
SELECT TO_CHAR(-1234.567, '09999.999')
FROM dual;

上に戻る

TO_NUMBER関数がエラーになる

公開日 2024/02/21

問題については正しい選択肢について理解しておりますが、次の選択肢に関して、エラーがなく正しく動作しているかどうか疑問があります。

SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual;
TO_NUMBER関数は、文字列を指定された書式にしたがって数値に変換します。変換された数値は¥やカンマを含むことは出来ないため、誤りです。

実際にクエリを実行したところ、無効な数値というエラーが発生しました。したがって、この選択肢はクエリ自体が無効である可能性があります。
なぜこのクエリがエラーになるのか、それは環境の違いによるものかどうかについては明確ではありませんが、ご教示いただけますと幸いです。

2024/02/21 16:37

このSQL文自体には特段問題はなく、言語環境の問題だと思います。
私はUTF8環境ですが、解説と同じ出力結果でした。
※検証用データの提供ページに「DBのキャラクタセットは「Unicode(AL32UTF8)」を想定」と記載されていたのでそれに従っていました。
問題文の冒頭で「実行環境は日本語とする」と言及しているのは、通貨記号「¥」が含まれているからですかね。

SQL> !echo $NLS_LANG
Japanese_Japan.AL32UTF8

SQL> select parameter, value from NLS_DATABASE_PARAMETERS where parameter = 'NLS_CHARACTERSET';

PARAMETER	     VALUE
-------------------- --------------------
NLS_CHARACTERSET     AL32UTF8

SQL> SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual;

TO_NUMBER('¥500,000.0','L999G999D0')
------------------------------------
			      500000

試しに英語に変えてみると、ORA-01722のエラー(「数値が無効です」のエラー)が発生しました。
通過記号「¥」が一致しなくなるためだと思います。

SQL> !echo $NLS_LANG
American_America.WE8MSWIN1252

SQL> SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual;
SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual
                 *
ERROR at line 1:
ORA-01722: invalid number

余談ですが、「$」などとすればエラーは発生しません。

SQL> !echo $NLS_LANG
American_America.WE8MSWIN1252

SQL> SELECT TO_NUMBER('$500,000.0', 'L999G999D0') FROM dual;

TO_NUMBER('$500,000.0','L999G999D0')
------------------------------------
			      500000


コメント

s sekakuma3

2024/02/22 21:45

確かに、"$"に変更したらエラーが発生せずに実行できました。 言語環境については完全に理解していませんが、文字列に通貨の記号やコンマが含まれていても、SQL自体に問題がないことを理解しました。 丁寧にご説明いただき、ありがとうございます。

この返信に対して
コメントを記入できます

この投稿に対して返信しませんか?