メニューを閉じる

テクノデジタルグループ

メニューを開く

2020.07.21

プログラミング

【Oracle】LISTAGG関数の暗黙の文字コード変換について

こんにちは。ZYです。
今回は、Oracle Databaseの集計関数である「LISTAGG」で暗黙的に行われている文字コード変換と、そのバージョンごとの差異についてです。

LISTAGGは、以下みたいな形で使うのですが、
この時、「Oracleのバージョンが古い」かつ「対象とするカラム(LAST_NAME)がNVARCHAR」だと、結果が文字化けします。

LISTAGG(LAST_NAME, '/') 
    WITHIN GROUP (ORDER BY LAST_NAME) AS LAST_NAME_LIST

ちなみに、Oracleのバージョンが12.1だと文字化けして、バージョン18cだと文字化けしませんでした。

なぜそんなことが起こるのか。
公式ドキュメントによると、この場合のLISTAGGの戻りデータ型はVARCHAR2になります。

メジャー列がRAW型である場合、戻り値のデータ型はRAWです。そうでない場合、戻りデータ型はVARCHAR2です。

カラムLAST_NAMEはNVARCHARなので、NVARCHAR→VARCHAR2への変換が行われている、ということになります。

そして、Oracleはデフォルトだと、以下のように文字コードが設定されています。
VARCHAR2 = AL32UTF8
NVARCHAR2 = AL16UTF16

どうやらNVARCHAR→VARCHAR2に変換する際のUTF16→UTF8への文字コード変換が、Oracle12.1は行われず、Oracle18だと暗黙的に行われているのが原因みたいです。
手元にあったバージョンが12.1と18cなので、それ以外は試せていませんが、この間のバージョンで暗黙の文字コード変換が入るようになったようです。
(公式ドキュメントやパッチノートを見ても、この文字コード変換に関する記述が見当たらなかったので、あくまで予想です)

では、古いOracle12.1では、どうすればいいかというと、以下のようにconvertで明示的に文字コード変換を行ってやると、文字化けを避けれます。

LISTAGG(CONVERT(LAST_NAME, 'UTF8'), '/') 
    WITHIN GROUP (ORDER BY LAST_NAME) AS LAST_NAME_LIST

最新バージョンでは対象のデータ型をほとんど意識せずに使えるようになっているので問題になることはあまりないかと思いますが、古いバージョンのOracleを使っている場合は参考にしてみてください。


【記事への感想募集中!】

記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!
  • こんな記事が読んでみたい、こんなことが知りたい、調べてほしい!という意見も募集中!
  • いただいた感想は今後の記事に活かしたいと思います!

感想フォームはこちら


【テクノデジタルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』

【テクノデジタルのインフラサービス】

当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。

https://www.tcdigital.jp/infrastructure/

最近の記事