質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

9747閲覧

PDOでSQLSERVERの日本語テーブル、日本語項目を取得

juriparu0411

総合スコア14

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2016/11/25 02:32

編集2016/11/25 03:55

###前提・実現したいこと
PHPでPDO接続でsqlserverを使用を試みていますが、日本語の項目名、テーブル名の場合、配列取得でエラーとなります。

英数字のテーブル、項目名は、正しく機能します。
(コードは、UTF8で記述)

どなたか、おわかりの方がいらっしゃいましたら、
日本語のテーブルを扱う方法をおしえていただけますでしょうか?

###発生している問題・エラーメッセージ

エラーメッセージ

PHP Notice: Undefined index: DPT in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 73
PHP Notice: Undefined index: DPT in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 74
PHP Notice: Undefined index: DPT略名_漢字 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 75
PHP Notice: Undefined index: DPT in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 73
PHP Notice: Undefined index: DPT in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 74
PHP Notice: Undefined index: DPT略名_漢字 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 75
PHP Notice: Undefined index: DPT in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 73
PHP Notice: Undefined index: DPT in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 74
PHP Notice: Undefined index: DPT略名_漢字 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 75

PHP

1<?php 2 3/** 4 * common.php 5 */ 6/** 7 * DSN 8 */ 9 10define('DSN_MSSQL', 'sqlsrv:server=.\sqlexpress;database=iryoumysql;'); 11 12/** 13 * エスケープ 14 */ 15function h($string) 16{ 17 return htmlspecialchars($string, ENT_QUOTES, 'utf-8'); 18} 19 20/** 21 * データベースコネクション 22 * @return \PDO 23 */ 24function db_con() 25{ 26 27 28 // MSSQL 29 $username = 'testuser'; 30 $password = 'testpass'; 31 $pdo = new PDO(DSN_MSSQL, $username, $password); 32 33 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 34 $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 35 return $pdo; 36} 37 38/** 39 * select 40 * @param string $sql 41 * @param array $params 42 * @return array 43 */ 44 45 46function select($sql, $params = array()) 47{ 48 $pdo = db_con(); 49 $stmt = $pdo->prepare($sql); 50 $stmt->execute($params); 51 return $stmt->fetchAll(); 52}

###該当のソースコード

PHP

1<?php 2/** 3 * index.php 4 */ 5ini_set('display_errors', 1); 6require 'common.php'; 7 8// 商品リストを検索 9 10$sql_items = 'SELECT DPT, DPT略名_漢字 FROM DPT'; 11print 'DPTマスタ select'; 12var_dump($sql_items); 13$arrItems = select($sql_items); 14var_dump($arrItems); 15 16 17// 購入履歴の検索 18if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') === 'POST') { 19 20 $arr = array(); 21 22 $sql_trading = 'SELECT '; 23 $sql_trading .= 'SUM(t.hatchusu) AS quantity'; 24 $sql_trading .= ', s.venmein as shop_name '; 25 $sql_trading .= ', i.dptmein as item_name '; 26 $sql_trading .= ', l.linmein as lin_name '; 27 $sql_trading .= 'FROM VM_nouhin_jisseki t '; 28 $sql_trading .= 'INNER JOIN ven_mast s ON s.ven = t.ven '; 29 $sql_trading .= 'INNER JOIN dpt_mast i ON i.dpt = t.dpt '; 30 $sql_trading .= 'INNER JOIN lin_mast l ON l.lin = t.lin '; 31// $sql_trading .= 'WHERE 1 '; 32 $sql_trading .= 'WHERE 1=1 '; 33 34 if (0 < filter_input(INPUT_POST, 'shop')) { 35 $sql_trading .= 'AND t.ven = :shop_id '; 36 $arr[':shop_id'] = filter_input(INPUT_POST, 'shop'); 37 } 38 if (0 < filter_input(INPUT_POST, 'item')) { 39 $sql_trading .= 'AND t.dpt = :item_id '; 40 $arr[':item_id'] = filter_input(INPUT_POST, 'item'); 41 } 42 43// $sql_trading .= 'GROUP BY t.shop_id,t.item_id,t.lin_id '; 44 $sql_trading .= 'GROUP BY s.venmein,i.dptmein,l.linmein'; 45 46 $arrTradings = select($sql_trading, $arr); 47// var_dump($sql_trading); 48} 49?><!DOCTYPE HTML> 50<html lang="ja"> 51 <head> 52 <meta charset="UTF-8"> 53 <title>Ajaxサンプル</title> 54 <style type="text/css"> 55 table { 56 border-collapse: collapse; 57 width: 600px; 58 } 59 table th, table td { 60 border: 1px solid #CCC; 61 } 62 </style> 63 </head> 64 <body> 65 <form method="post"> 66 <p> 67 <label for="item">DPT</label> 68 <select name="item" id="item"> 69 <option value="">---- 選択してください ----</option> 70 71 <?php foreach ($arrItems as $item) : ?> 72 73 <?php if ($item['DPT'] == filter_input(INPUT_POST, 'item')): ?> 74 <option value="<?= h($item['DPT']); ?>" selected="selected"> 75 <?= h($item['DPT略名_漢字']); ?> 76 </option> 77 <?php else: ?> 78 <option value="<?= h($item['DPT']); ?>"> 79 <?= h($item['DPT略名_漢字']); ?> 80 </option> 81 <?php endif; ?> 82 83 <?php endforeach; ?> 84 </select>

###試したこと
エラーが出ている箇所の日本語項目名をバックックオート(`)で囲みましたが、エラーのままでした。

$item[0]、$item[1]にソ-スを変更しましたが、
エラーメッセージは同じでした。

PHP Notice: Undefined offset: 0 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 73
PHP Notice: Undefined offset: 0 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 74
PHP Notice: Undefined offset: 1 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 75
PHP Notice: Undefined offset: 0 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 73
PHP Notice: Undefined offset: 0 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 74
PHP Notice: Undefined offset: 1 in C:\inetpub\wwwroot\php\pdo_nihongo\index.php on line 75

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

PHP Version 5.4.45
IIS7.0
Microsoft SQL Server 2008 R2 Express

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

alg

2016/11/25 02:47

14行目の`var_dump($arrItems);`の出力結果はどうなっていますか?
juriparu0411

2016/11/25 02:52

ディスプレイには、エラーメッセージしか出力されておりません。selectを実行していないのではと思っています。
juriparu0411

2016/11/25 02:58

先ほどの投稿の修正です。エラーメッセージは、3行(line 73,74,75) ☓ 90組みほど出力しているので、SELECTはできているかもしれません。
kunai

2016/11/25 03:12

ただの配列のインデックスエラーのようですね。<?php foreach ($arrItems as $item) : ?>の直後に<?php var_dump($item); ?>とかしてみたらいかがでしょう
juriparu0411

2016/11/25 03:24

<?php foreach ($arrItems as $item) : ?>の直後に<?php var_dump($item); ?>を入れましたがDISPLAYには出力されませんでした。
guest

回答3

0

ベストアンサー

SQLServer は Windows で動作するものですから、
テーブル名、およびカラム名は CP932(SJIS-WIN)の文字コードとなります。
Ajaxを利用するという条件ではスクリプトは UTF-8を使うことが推奨されますから、データベースのカラム名にはマルチバイトを使わず、シングルバイトで定義するのがベストプラクティスです。

投稿2016/11/25 04:37

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juriparu0411

2016/11/25 08:34

早速のご確認ありがとうございます。また、ご指導いただいたソースを無断で公開してしまい失礼いたしました。実は、社内のシステムはVB.NET、レガシーASPで開発している案件も多く、DBのテーブル、項目名が日本語項目になっていて質問した次第です。やはりシングルバイトなんですね。よく考えてみます。
退会済みユーザー

退会済みユーザー

2016/11/25 08:38 編集

場当たり的な対処としては、DB側にViewでシングルバイトにしたものを作ってしまうという手も考えられなくはありません。 カラム名をいちいち、mb_convert_encoding するよりはソースコードもスッキリするでしょう。
juriparu0411

2016/11/25 09:21

Viewでの対応は思いつきませんでした。これ名案ですね。やりたいことに必要な項目を整理して試してみます。
guest

0

var_dump($arrItems);
しているようですが、そこで各要素に「DTP」をキーにした値はありませんか?
正直肝心のPDOの部分が書いていないのでなんとも言えません
実行していないのであれば実行してください

追記

SQLサーバーとPDO、文字コードの相性があるので明示的に
$pdo->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND,'SET NAMES utf8');
を実行してみるとかですかね
一般に$dsn内で「;charset=UTF8」をつけるんですけどね

その上でどうしても文字化けするようならarray_walkで付け替えてください

PHP

1$a=["あああ"=>"いいい","ううう"=>"えええ"];//元データをsjisやeucで書いておいて 2$b=[];//UTF8用の配列に流し込む 3array_walk($a,function($val,$index) use(&$b){ 4 $b[mb_convert_encoding($index,'UTF8','EUCJP,SJIS')]=mb_convert_encoding($val,'UTF8','EUCJP,SJIS'); 5 }); 6print_r($b); 7

投稿2016/11/25 03:10

編集2016/11/25 04:36
yambejp

総合スコア114747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juriparu0411

2016/11/25 03:34

PDOの記述を追加投稿いたしました。何かおわかりになれば、よろしくお願いいたします。 「DTP」をキーにした値は、var_dumpでもDISPLAYされませんでした。
yambejp

2016/11/25 03:55

では、var_dump($arrItems)では具体的にどういったデータが表示されているのでしょうか? 正直RDBのテーブルやカラムに日本語をつかうということは リスクを自分で解決できるだけのスキルが必要なんですけどね・・・ とりあえず日本語名の問題で戻り値がえられないのであれば $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); を取りやめてASSOCではない列番号でのデータ抜き出しなど検討したほうがよいかもしれません
juriparu0411

2016/11/25 04:07

確かに PDO::FETCH_BOTH にして、$item[0]、$item[1]にソ-スを変更すると動作しますが、テーブルを多く使う場合、現実的な対応でないと思われ困っているところです。 ちなみに、var_dump($arrItems)では、DPTマスタ selectarray(99) { [0]=> array(4) { ["�c�o�s"]=> string(4) "10.0" [0]=> string(4) "10.0" ["�c�o�s����_����"]=> string(9) "  米" [1]=> string(9) "  米" }.....が表示されます。
yambejp

2016/11/25 04:37

文字化けしているだけであれば、変換処理を入れればよいかもしれません 追記しておきました
juriparu0411

2016/11/25 08:41

ありがとうございます。試してみます。
Y.H.

2016/11/25 08:45

SQL文を "SELECT DPT DPT, DPT略名_漢字 DPT_SHORTNAME FROM DPT" として取得項目にANKの別名付ければ それぞれ "DPT"と"DPT_SHORTNAME"で取れないですかね?
juriparu0411

2016/11/25 09:24

コメントありがとうございます。 $pdo->setAttribute(PDO::MSSQL_ATTR_INIT_COMMAND,'SET NAMES utf8'); こちらは、エラーになります。 PHP Fatal error: Undefined class constant 'MSSQL_ATTR_INIT_COMMAND' in C:\inetpub\wwwroot\php\pdo_nihongo\common.php on line 39
juriparu0411

2016/11/25 09:32

"SELECT DPT DPT, DPT略名_漢字 DPT_SHORTNAME FROM DPT"⇒こちらで動きました。 ありがとうございます。
Y.H.

2016/11/25 09:57

@juriparu0411 動きましたか。この対応は今後のメンテナンス時のことを考えるとかなりバッドノウハウ(DB定義変更などによるプログラムへの影響調査など行う時にDBの項目名などで検索できないなど)です。 正対応としては本来の項目名で取得できるようにすべきなので、であまり多用はなさらないように。
juriparu0411

2016/11/26 02:35

承知いたしました。SQLSERVER自体がSJISなので、無理に文字コードを合わせるのは難があるようですね。ご指導ありがとうございました。
guest

0

PHP

1define('DSN_MSSQL', 'sqlsrv:server=.\sqlexpress;database=iryoumysql;charset=UTF-8');

↑のように、SQLServer側の文字コードを指定してみたら通るのでは

投稿2016/11/25 04:35

kunai

総合スコア5405

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

juriparu0411

2016/11/25 08:38

charsetは指定できないようですね。 PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[IMSSP]: An invalid keyword 'charset' was specified in the DSN string.' in C:\inetpub\wwwroot\php\pdo_nihongo\common.php:35 Stack trace: #0 C:\inetpub\wwwroot\php\pdo_nihongo\common.php(35): PDO->__construct('sqlsrv:server=....', 'sa', 'sa') #1 C:\inetpub\wwwroot\php\pdo_nihongo\common.php(53): db_con() #2 C:\inetpub\wwwroot\php\pdo_nihongo\index.php(13): select('SELECT \xEF\xBC\xA4\xEF\xBC\xB0\xEF\xBC...') #3 {main} thrown in C:\inetpub\wwwroot\php\pdo_nihongo\common.php on line 35
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問