2008年6月16日月曜日

[MySQL]--SELECTで文字化の対応。

【目的】CONCAT()関数で日本語を連結して、文字化したトキの対処。


●切っ掛け
 以下の様に、CONCAT()関数を使用して文字を連結して、SELECTで抽出してファイルに出力したら、文字化けした。
      *MySQLマニュアル:文字列関数

 (各カラムの値: a.intA = 1, a.intB = 2, a.intC = 3 )
 [修正前SQL] SELECT CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' )
      FROM DataTbl a
 [実際の結果] 1蟷エ2繝カ譛・譌・
 [欲しい結果] 1年 2ヶ月 3日

 で、ネットで検索して解決したので、メモっとくのです。


○解決方法
 1.先ず、CONCAT()関数を使用しているカラムの文字セットを確認。
   文字セットの確認は、CHARSET(str)関数を使う。
   CHARSET()関数は、'str'の文字セットを返してくれる関数。
      *MySQLマニュアル:情報関数

   [SQL] SELECT CHARSET( CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' ) )
   [結果] binary

   文字列(型)で返してほしいのに「binary」という結果。
   なので、型を文字列型にキャストすることにした。

 2.integer型⇒char型へキャストして、連結する。
   キャストには、CAST()関数を使用。
   CAST()関数は以下のように使用する。
     CAST( 変換する値 AS 変換したい型)
      *MySQLマニュアル:キャスト関数と演算子

   ちなみに、各値に対してキャストする必要がある。
   CONCAT()毎括ってキャストしようとしても、エラーになる。
   [例SQL] CAST(CONCAT( a.intA, '年 ', a.intB, 'ヶ月 ', a.intC, '日' ) AS CHAR)
   これはエラーを返される。

   で、以下のように修正。

   [SQL]SELECT CONCAT( CAST( a.intA ) AS CHAR, '年 ', CAST( a.intB ) AS CHAR, 'ヶ月 ', CAST( a.intC ) AS CHAR, '日' )
     FROM DataTbl a
   [結果]1年 2ヶ月 3日


   うん。思うとおりの結果。各値毎にキャストするのは、ちょいと面倒ですけど。
   念のため、CHARSET()関数で文字セットを確認。

   [SQL] SELECT CHARSET( CONCAT( CAST( 1 AS CHAR ), '年 ', CAST( 2 AS CHAR ), 'ヶ月 ', CAST( 3 AS CHAR ), '日' ) )
   [結果] utf8

   OK。
 
 
 

1 件のコメント:

匿名 さんのコメント...

[SQL]SELECT CONCAT( CAST( a.intA ) AS CHAR, '年 ', CAST( a.intB ) AS CHAR, 'ヶ月 ', CAST( a.intC ) AS CHAR, '日' )

誤記があったので指摘させて頂きました。

【誤】
CAST( a.intA ) AS CHAR
CAST( a.intB ) AS CHAR
CAST( a.intC ) AS CHAR

【正】
CAST( a.intA AS CHAR )
CAST( a.intB AS CHAR )
CAST( a.intC AS CHAR )