こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

SQL Serverで文字コードUTF-8

こんにちわ。
いつも拝見しております。

PHPでODBC接続によるSQL Serverへの問い合わせを行う部分でエラーが出て困っております。

odbc_exec()[function.odbc-exec]:SQL error:[Microsoft][ODBC SQL Server Driver][SQL Server][文字化けしたSQL文]SQL state 37000 in SQLExecDirect in C://.......

SJISの時は問題なかったのですがcharsetや保存形式をUTF-8に統一してから出るようになりました。

SQL文は下記のように日本語となっております。
$str = "select 担務,部課 from group by id";

解決策がありましたらご教示下さい。

よろしくお願い致します。

投稿日時 - 2009-07-03 11:18:45

QNo.5094557

困ってます

質問者が選んだベストアンサー

>SJISの時は問題なかったのですがcharsetや保存形式をUTF-8に統一してから出るようになりました。
SQL Serverの文字コードはUTF-8になっているということでしょうか。
また、PHPのマルチバイト文字関連の設定を詳しく教えてください。

投稿日時 - 2009-07-03 17:12:37

補足

UmJammerさん

ありがとうございます。

SQL Serverの文字コードは恥ずかしながら確認方法が分かりませんでしたので調べてみます。

文字関連の設定を記載させて頂きます。
【php】
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
と記述してUTF-8で保存しました。
【php.ini】
magic_quotes_gpc = Off
extension_dir = "C:/php/ext"
extension=php_mbstring.dll
extension=php_mssql.dll
extension=php_pdo.dll
extension=php_pdo_mssql.dll
extension=php_pdo_odbc.dll

[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1

[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = auto
mbstring.http_output = UTF-8
mbstring.encoding_translation = On
mbstring.detect_order = auto
mbstring.substitute_character = none

このような形になっております。
どうぞよろしくお願い致します。

投稿日時 - 2009-07-03 18:41:53

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(9)

ANo.9

DBのデータはSJIS、内部エンコードおよび出力はUTF-8なので、取得したデータを正しく表示するにはやはり文字コードを変換しなければなりません。
というような意味で取り扱いには注意しましょうと書いたのですが、回りくどすぎましたね。

先ほどの回答の$clm1をUTF-8に変換して出力してみてください。

echo mb_convert_encoding($com1, "UTF-8", "SJIS");

これでPHPの設定に変更がなければこれで正しく表示されるはずです。

気になったのですが、
>DBのSJISの問題はまだ解決していないのですが
これはつまるところDBもUnicode(UTF-8)に変更するということでしょうか。であればそちらを優先しなくてはダメですよ。
というよりPHPのコーディングなどしてる場合ではないです。
というのも、DBがUnicode(UTF-8)になれば、文字コードの変換処理は不要になりますから。
まぁちょっとした勉強にはなったかもしれませんが。。

投稿日時 - 2009-07-07 11:56:39

お礼

UmJammerさま

ありがとうございます。
うまく表示されました!

DBもUnicode(UTF-8)に変更しない予定のようですので今はPHP側で変換処理をしていこうと思います。

仰るとおりとてもいい勉強にもなりました!

数日に渡りご教示頂きましてありがとうございました。

感謝しております。

投稿日時 - 2009-07-07 14:03:34

ANo.8

ANo.1です。たびたびすいません。

また訂正です。。
×$clm1 = odbc_result($r, mb_convert_encoding("0120担当者", "SJIS", "UF-8");
○$clm1 = odbc_result($r, mb_convert_encoding("0120担当者", "SJIS", "UTF-8"));

投稿日時 - 2009-07-07 11:00:03

補足

UmJammerさん

ご教示ありがとうございます。

odbc_result($r, mb_convert_encoding("0120担当者", "SJIS", "UTF-8"));

でNot Fieldのエラーは解消しましたが文字化けしてしまっているようです。
「~??~??」みたいな感じです。

DBのSJISの問題はまだ解決していないのですがこちらを解決しなければこの文字化けは解消しないのでしょうか?

度々、すみませんがよろしくお願い致します。

ご教示のおかげでここまで来ることができました。
ありがとうございます。

投稿日時 - 2009-07-07 11:25:34

ANo.7

ANo.1です。

>mb_detect_encoding($clm1)
>としてみると「ASCII」と表示が出ました。
ここは一旦放っておいても平気です。

問題は、
>$clm1 = odbc_result($r,"0120担当者");
この「0120担当者」は内部エンコーディング(UTF-8)で記述されているので、SJISのDBのフィールド名とは合致しないのではないかと思うのですが、それともエラーは解決したのでしょうか。
未だエラーが出るようでしたら、ここを

$clm1 = odbc_result($r, mb_convert_encoding("0120担当者", "SJIS", "UTF-8");

と書きなおして実行してみてください。
#これならはじめの方に質問者様が書いたようにフィールド名ごとに文字コード変換をして変数に格納しておく方が効率的でしたね。。
#もしくはすべてAS句で半角英数の別名をつけた方がまだ楽かもしれないですね。

ところで、これで無事にDBからデータが取得できてもその値もやはりSJISなのでその取扱いには注意してください。

投稿日時 - 2009-07-07 10:51:39

ANo.6

ANo.1です。

補足説明ありがとうございました。
SQLが間違ってるのかと思っていたのですが、odbc_resultでエラーなので違いますね、こちらこそ申し訳ありませんでした。

で、ここからはコードが省略されているので予想ですが、
odbc_resultで「0120担当者」を取得するときにフィールド名で取得しに行っていると思うのですが、これがSJISでないということはないですか?
DBがSJISだとすると、フィールド名もSJISなので内部エンコーディング(UTF-8)で「0120担当者」と書いても通らないはずです。

投稿日時 - 2009-07-06 20:20:59

補足

UmJammerさん

おはようございます。
仰るとおり
$clm1 = odbc_result($r,"0120担当者");
で取得しております。

mb_detect_encoding($clm1)
としてみると「ASCII」と表示が出ました。

どうぞ宜しくお願い致します。

投稿日時 - 2009-07-07 10:11:45

ANo.5

ANo.1です。たびたびすいません。

訂正です。
>「担当者」というフィールドではなかったのですか?
ここ、「担当者」でなくて「担務」です。

投稿日時 - 2009-07-06 15:31:33

補足

UmJammerさん

大変失礼致しました。
先ほど指示があり多少、項目が変更となってしまいました。

$str = "select [0120担当者],個数 AS Count from datatbl group by id";
こちらが確定版です。

エラーメッセージは抜粋ではないです。
画面にエラーだけが表示されているわけではなくCountについてはHTML表示されており先ほどのエラーメッセージが上に表示されている状態です。

SQL文のフィールドは確かに存在する事を確認しております。
わかりづらく申しわけございませんでした。

投稿日時 - 2009-07-06 16:07:42

ANo.4

>[function.odbc-result]:Fied 0120担当者 not found in
これって、「0120担当者」というフィールドがないってメッセージですかね。「担当者」というフィールドではなかったのですか?
エラーメッセージは抜粋ですか?であれば全部載せた方が回答が得られやすいと思います。

投稿日時 - 2009-07-06 15:24:04

ANo.3

ANo.1です。

>おっしゃっている内容は

>$clm1 = mb_convert_encoding("担務",'SJIS')
>$clm2 = mb_convert_encoding("部課",'SJIS')

>$str = "select $clm1,$clm2 from group by id";

>上記のようにするといった認識で宜しいでしょうか?
問題ないと思いますが、SQLを投げるだけだったら以下でもよいかと思います。

$str = "select 担務,部課 from group by id";
$str = mb_convert_encoding($str, "SJIS", "UTF-8");

これでSQLが通るようになるかもしれませんが、やはりDBの文字コードもUnicode(UTF-8)にした方がなにかと都合がよいです。
あとは、フィールド名などにマルチバイト文字を使うのはあまりよくないような。。

投稿日時 - 2009-07-04 03:10:02

補足

UmJammerさん

どうもありがとうございます。
本日、やっと試すことができたのでお返事が遅くなりました。

ご教示頂いた記述でSQLは通りました。
しかしresultの部分で
***************************************************
[function.odbc-result]:Fied 0120担当者 not found in
***************************************************
と出てしまいました。

mb_detect_encodingをprintするとASCIIとなっていましたがこれはどの様にコーディングするといいのでしょうか?

同じようにmb_convert_encodingを使ってみましたが改善されませんでした。

度々の質問で恐縮ですがよろしくお願いします。

ソースは以下のようになっております。

-----------------------------------------------------
$db = odbc_connect("web","test","test");
$str = "select [0120担当者],部課 from group by id";
$str = mb_convert_encoding($str, "SJIS", "UTF-8");
$r = odbc_exec($db,$str);
while(odbc_fetch_row($r)){
$clm1 = odbc_result($r,"");
~HTMLで<?= $clm1 ?>を出力~
}
-----------------------------------------------------

投稿日時 - 2009-07-06 11:38:29

ANo.2

ANo.1です。

補足説明ありがとうございます。
PHPの方は完全にUTF-8に対応していますね。
もしかするとSQL Serverの文字コードがSJISなのかもしれません。
SQL文の文字コードを、発行される前にSJISに変換してみるとどうでしょうか。

投稿日時 - 2009-07-03 23:36:19

補足

UmJammerさん

こちらこそご教示頂きありがとうございます。

おっしゃっている内容は

$clm1 = mb_convert_encoding("担務",'SJIS')
$clm2 = mb_convert_encoding("部課",'SJIS')

$str = "select $clm1,$clm2 from group by id";

上記のようにするといった認識で宜しいでしょうか?

知識不足の為、お手数をおかけしますがよろしくお願い致します。

投稿日時 - 2009-07-04 01:57:47

あなたにオススメの質問