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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

Q&A

解決済

2回答

2628閲覧

PDOで複文取得する方法が分からない

___knd

総合スコア12

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

0グッド

1クリップ

投稿2016/01/10 01:31

編集2016/01/10 03:26

PHPでPDOを用いてmysqlからデータの取得を行おうとしております。
そこで、

$sql = 'SELECT * FROM ***;'; $stmt = $pdo -> query($sql); if(!$stmt){ $info = $pfo ->errorInfo(); exit($info[2]); } while($data= $stmt ->fetch(PDO::FETCH_ASSOC)){ echo $data['**']; }

このようにして必要なデータを取り出すことには成功したのですが、複文を書きたいときにエラーが出てしまいます。
具体的には

$sql = 'SELECT ** FROM ***; SELECT xx FROM xxx;'; $stmt = $pdo -> query($sql); if(!$stmt){ $info = $pfo ->errorInfo(); exit($info[2]); } while($data= $stmt ->fetch(PDO::FETCH_ASSOC)){ echo $data['**']; echo $data['xx'];

このように書いたのですがxxが見つからない?というようなエラーが出ます。

どのようにすれば複文記述することができるのかご教授願いたいです。説明不足であれば追記します。

環境はMAMPでPHPのバージョンは7.00です。

以上、よろしくお願いします。


2016/1/10追記

ご解答ありがとうございます。

$sql = 'SELECT ** FROM ***;'; $sql1 = 'SELECT xx FROM xxx;'; $stmt = $pdo -> query($sql); $stmt1 = $pdo -> query($sql1); while($data= $stmt ->fetch(PDO::FETCH_ASSOC)){ echo $data['**']; } while($data1= $stmt1 ->fetch(PDO::FETCH_ASSOC)){ echo $data['xx']; }

複文記述する際、このような感じでデータを取れることは理解しました。(命令をstmtに保存してるイメージなのかなという解釈です)
ただこれだと、[0],[1]…xx[0],xx[1]となってしまいます。

――――――――――――――
|[0]|xx[0]|
|
[1]|xx[1]|
|**[2]|xx[2]|
――――――――――――――
このように交互にデータの取得を行いたいです。

while文内では、データに命令されたデータを代入しある分を保持→表示しているのかなという解釈をしていて、
それだとwhile文の中にwhile文を書いてもやりたい処理はできなく困っています。

交互にデータを取ってくる処理のご教授をお願いしたいです。

何度もすみません。よろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

対応策はg737a6bさんが記載してくださってるので、その解説でも…

PDOは基本的に複数のSQLを同時に発行出来ない仕様だったかと思います。
よくあるSQLインジェクション対策です。

SQL自体は正常に発行されて、
echo $data['xx']の行で$dataにはxxなんてキーは存在しねーよというエラーが出てるかと思います。
最初のSQL文章だけ処理されて、後者は切り捨てられてるからかと思います。
具体的な動作は確認してみてください。

投稿2016/01/10 02:51

miyabi-sun

総合スコア21158

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

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

___knd

2016/01/10 03:30

ありがとうございます。 そもそもの仕様だったのですね。いくら調べてもヒットしないわけです。 今までの文でだめな理由が解説を見て理解することができました。エラーが出てこないので読み込まれてはいると勝手に思い込んでおりました… やりたいことを具体的に追記したので、もしよろしければそちらもよろしくお願いします。
miyabi-sun

2016/01/10 03:50

そもそもなぜ交互に情報を得る必要があるのか… そこを質問してもいいですか? 「交互」の部分に相関がなく、 単純に見栄えだけならば私の目線からみて相当見づらいです。 それでも教えてほしいというのであれば…仰ってください。 例えばmiyabiっていうユーザーが居たとして、 ***テーブルはmiyabiユーザーの加入しているプラン xxxテーブルはmiyabiユーザーのスコアが一意に決まる状態で、 2つのSQLがmiyabiユーザーの情報になるから表示したいのでしょうか? 仮に上記の目的そうしたいのであれば、SQLの外部結合を使って一撃でやるべきでしょう。 SELECT ***.user_id, ***.id as plan_id, xxx.score FROM *** LEFT JOIN xxx ON ***.user_id = xxx.user_id こんな感じになるかと思います。
___knd

2016/01/10 05:10

解答ありがとうございます。 そうですね…。***テーブルでmiyabiユーザーの情報(加入しているプランのID、年等)のコードがはいっていて、xxxテーブルでmiyabiユーザーが加入しているプランのIDを元にいくら費用が必要であるのか…というようなことをしたいです。 今結合について少し調べてみましたが二つのテーブルを一つにしてそこからデータを抽出するということができるのですね。 ちょっとやってみてるのですが… ***テーブルのプランIDとxxxテーブルのプランIDが一致した場合、***テーブルのプラン費用を取得したいです。 $sql = 'SELECT ***.プラン費用 FROM xxx INNER JOIN *** ON xxx.プランID = ***.プランID WHERE xxx.プランID = ***.プランID'; こう書いてみているのですが、全てのデータが取得されてしまうのは何故なのでしょうか… 初歩的な質問を重ねてしまってすみません。 よろしくお願いします。
miyabi-sun

2016/01/10 09:03

なるほどなるほど… やはりそのような意図があったのですね。 >全てのデータが取得されてしまうのは何故なのでしょうか… 結合条件と抽出条件が全く同じなのでフィルタリングされないからです。 基本的にSQLの結合は直積です。 更に高度になりますが集計という概念を使う感じになるかと思います。 下記のように仮定してSQLを作ってみます ・xxxがユーザー一覧(ユーザーID, プランID) ・***がプラン一覧(プランID, プラン費用) SELECT xxx.ユーザーID, ***.プランID, ***.プラン費用 FROM xxx INNER JOIN *** ON xxx.プランID = ***.プランID これで全ユーザーかつ全プランの情報が表示されます。 例えば「今月の」「ユーザーIDが33番の」という条件をWhere句に入れてあげます WHERE date_format(xxx.加入日, '%Y-%m') = '2016-01' AND xxx.ユーザーID = 33 もし、ユーザーが一度に複数プランに加入しつつ、合計金額を得たいのであればこんな感じになるでしょう。 (usersテーブルを追加して考えます) これは集計関数を使ったさらに複雑な概念になりますが、分かれば強力な武器となるので頑張ってください SELECT users.id as user_id, sum(***.プラン費用) as amount FROM users INNER JOIN xxx ON xxx.ユーザーID = users.id INNER JOIN *** ON ***.プランID = xxx.プランID -- <- Where句で絞りたい場合は此処に差し込む GROUP BY users.id;
___knd

2016/01/10 12:52

こちらの書いていない意図まで読み取っていただいてありがとうございます。 >>全てのデータが取得されてしまうのは何故なのでしょうか… >結合条件と抽出条件が全く同じなのでフィルタリングされないからです。 なるほど。そういわれるとそうですよね…超当たり前ですよね…。 自分で調べて出来ました!!という報告をしたかったのですがもう少々お付き合いいただけると幸いですorz ・xxxがユーザー一覧(ユーザーID, プランカテゴリ、プランランク) ・***がプラン一覧(プランID, プラン費用) だとして、プランカテゴリがA,B,C…プランランクが001,002…プランIDがA001,A002…という状況です。 なので、結合条件を***テーブルのプランIDとxxxテーブルのプランカテゴリ||xxxテーブルのプランランクとすれば ユーザーID|プランID|プランカテゴリ|プランランク|プラン費用 たろう  | A001 | A | 001 | 100000 はなこ | A002 | A | 002 | 150000 といった結果が出てきてくれるのかなあと思ったのですが、 たろう  | A001 | A | 001 | 100000 たろう  | A001 | A | 002 | 150000 はなこ  | A002 | A | 001 | 100000 はなこ | A002 | A | 002 | 150000 このようにすべての組み合わせが出てきてしまいます。 今回、私のやりたいことは抽出条件と結合条件が一致しているので、WHERE文を書かずに終了するのではないのかなと考えているのですがいかがでしょうか。 SELECT * FROM xxx INNER JOIN *** ON ***.プランID=xxx.プランカテゴリ||xxx.プランランク 記述の仕方が悪いのでしょうか、考え方が間違えているのでしょうか… 以上、よろしくお願いします。
guest

0

命令文の数だけ$stmt = $pdo->query($sql);のようにステートメントを作成してください。

投稿2016/01/10 02:28

編集2016/01/10 02:33
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

___knd

2016/01/10 03:27

ありがとうございます。実行してみたところ、正直どのように処理されているのか分からなかったのですがなんとなくイメージできるようになりました。(理解はまだまだ浅いのですが…) しかし、やりたいことが上手くいかずに追記に書いたので、もしよろしければそちらも教えていただきたいです。よろしくお願いします。
退会済みユーザー

退会済みユーザー

2016/01/10 03:44

交互に出力するのであれば、このようにすればどうですか。 while( true ){ $br = 0; if( $data = $stmt ->fetch(PDO::FETCH_ASSOC) ){ echo $data["**"]; }else{ $br++; } if( $data1 = $stmt1 ->fetch(PDO::FETCH_ASSOC) ){ echo $data["xx"]; }else{ $br++; } if( $br >= 2 ) break; }
___knd

2016/01/10 04:30

解答ありがとうございます。 なるほど。もし両方データがなくなったら終わるような仕組みを作ればいいのですね。私のやりたいことができました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問