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

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

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

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

mysqli

MySQLiはPHP5より導入されているデータベース用のドライバです。MySQL 4.1.3以降の新しい機能の利点をまとめています。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

3939閲覧

mysqli_query()を削除、更新ともに1回に押さえたい

a-_.

総合スコア133

MySQL

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

mysqli

MySQLiはPHP5より導入されているデータベース用のドライバです。MySQL 4.1.3以降の新しい機能の利点をまとめています。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2016/08/16 01:25

編集2016/09/06 02:25

データベースへのアクセス回数を減らすべく、mysqli_queryでの更新・削除処理を一回にまとめたいと思って、where句にandを追加して下記コードを書いてみたんですが、foreach文では処理できない様で他のループ文を書いてみようと試みてるんですが、他のループ文の条件式をどのように書けばいいのか調べても不明です
ご指摘いただけませんか

PHP

1 $link = mysqli_connect($host, $user, $pass, $dbname) or die("NG"); 2 3 mysqli_select_db($link, "XXX"); 4 5 if (isset($_POST['name'], $_POST['comment'], $_POST['bbs']) && $_POST['bbs'] == "post") { 6 $name = $_POST['name']; 7 $comment = $_POST['comment']; 8 mysqli_query($link, "INSERT INTO XXX (name, comment) VALUES ('$name', '$comment')"); 9 } elseif (isset($_POST['bbs']) && $_POST['bbs'] == "update") { 10 foreach($_POST['chkid'] as $id) { 11 $name = $_POST['name']; 12 $comment = $_POST['comment']; 13 $update = $id; 14 $delete = $id; 15 mysqli_query($link, "UPDATE XXX SET name = '$name', comment = '$comment' WHERE id = $update and DELETE FROM XXX WHERE id = $delete"); 16 } 17 } 18 19 $result = mysqli_query($link, "SELECT * FROM XXX ORDER BY time DESC"); 20?> 21 22<html> 23 <head> 24 <meta http-equiv="content-type" content="text/html; charset=utf-8"> 25 </head> 26 <body> 27 <form method="post" action=""> 28 <table> 29 <tr> 30 <td> 31 名前:<input type="text" name="name"> 32 内容:<textarea name="comment" cols="30" rows="3"></textarea> 33 <input type="radio" name="bbs" value="post" checked>投稿 34 <input type="radio" name="bbs" value="update">更新 35 <input type="radio" name="bbs" value="delete">削除 36 <input type="submit" value="投稿"> 37 </td> 38 </tr> 39 </table> 40 41<?php 42 while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { 43?> 44 45 <table> 46 <input type="checkbox" name="chkid[]" value="<?=$row['id'] ?>"> 47 <tr> 48 <td>名前: 49 <?php echo $row['name'] ?> 50 </td> 51 </tr> 52 <tr> 53 <td>内容: 54 <?php echo $row['comment'] ?> 55 </td> 56 </tr> 57 </table> 58 59<?php 60 } 61 mysqli_free_result($result); 62 63 mysqli_close($link); 64?> 65 66 </form> 67 </body> 68</html>

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

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

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

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

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

guest

回答2

0

ベストアンサー

DB側に投げるSQLステートメント自体が誤ってます。

AND句を用いてのINSERT文、UPDATE文、DELETE文を連結できません。
そのためSQL構文エラー(MySQL側によるエラー通知)となっているものと思われます。

maisumakunさんのおっしゃられるように、UPDATE句とDELETE句を同時に実行するメリットより実装のややこしさなどによるデメリットの方が大きいので、
それぞれ1文ずつでmysqli_queryでするようにすると良いでしょう。

###補足
ロジック誤りは既に指摘されてるので僕からはそれ以外で2点ほどアドバイス。

先ずは1点目。
INSERT、UPDATE、DELETEの実行時のmysqli_query戻り値は、
SQL実行が正常終了したらTRUE失敗(SQL実行時エラーなど)したらFALSEを返却するので、

SQL実行が成功したか判定するための処理を加えることをお勧めします。

以下は利用例

PHP

1 $success = mysqli_query($link, $sql) // INSERT、UPDATE、DELETEの場合 2 3 if (!$success) { 4 // SQL実行エラー時の処理 5 }

最後に2点目。
INSERT、UPDATE、DELETEでは、
更新・削除件数が0件であってもSQL実行が正常であればTRUEを返却するので、
例えば指定したIDでの更新件数が0件の場合は想定外としたい場合は、
mysqli_affected_rows関数の利用をお勧めします。

以下は利用例

PHP

1 $success = mysqli_query($link, $sql) // INSERT、UPDATE、DELETEの場合 2 3 // 1つ目のサンプルと判定逆ににしてるので注意 4 if ($success) { 5 // SQL実行成功時 6 if (mysqli_affected_rows( mysqli $link ) === 0) { 7 // 更新件数0件の場合はエラーとするならここに処理記載 8 } 9 10 } else { 11 // SQL実行エラー時の処理 12 }

投稿2016/08/16 02:38

Panzer_vor

総合スコア1636

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

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

a-_.

2016/08/16 04:30

ご回答ありがとうございます 質問投稿後も調べて確かにAND句はふさわしくないことが分かりました 改めてコードを書き直し、AND句の代わりにIN演算子を用いてIDの特定をやってみようかと思いました 下記コードはIN演算子を用いたコードなんですが、Notice: Undefined index: idと表示され、IDをどう式に反映させればデータベースのIDと認識させられるのかが分かりません } elseif (isset($_POST['bbs']) && $_POST['bbs'] == "update") { foreach($_POST['chkid'] as $id) { $name = $_POST['name']; $comment = $_POST['comment']; $id = $_POST['id']; mysqli_query($link, "UPDATE XXX SET name = '$name', comment = '$comment' WHERE id in('$id')"); } } elseif (isset($_POST['bbs']) && $_POST['bbs'] == "delete") { foreach($_POST['chkid'] as $id) { $id = $_POST['id']; mysqli_query($link, "DELETE FROM XXX WHERE id in('$id')");
guest

0

WHERE id = $update and DELETE FROMなんて書き方はできません。セミコロンで区切れば複数の分を並べることもできますが、複数の文を一気に実行するには専用の書き方が必要となって、余計にややこしくなります。

似たようなSELECTを大量に発行する状況から「削減したい」のならともかく、UPDATEDELETEを一気にやることにそこまでメリットはないと考えます。

投稿2016/08/16 01:32

maisumakun

総合スコア145121

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

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

a-_.

2016/08/16 01:34

ご回答ありがとうございます ではどのような処理が適当なんでしょうか
maisumakun

2016/08/16 01:36

それ以前に、$updateも$deleteも同じ$idなので、仮にそのまま実行しても「行をUPDATEした直後にDELETE」となってしまって、UPDATEが完全なる無駄となってしまうようなのですが、実行すべきロジック自体に誤りがあるように思います。
a-_.

2016/08/16 01:53

$updateも$deleteも同じ$idにしないと、どの$idを更新・削除するのか特定できないため書きました 因みにですが、訂正前は下記コードでした } elseif (isset($_POST['bbs']) && $_POST['bbs'] == "update") { foreach($_POST['chkid'] as $id) { $name = $_POST['name']; $comment = $_POST['comment']; $update = $id; mysqli_query($link, "UPDATE XXX SET name = '$name', comment = '$comment' WHERE id = $update"); } } elseif (isset($_POST['bbs']) && $_POST['bbs'] == "delete") { foreach($_POST['chkid'] as $id) { $delete = $id; mysqli_query($link, "DELETE FROM XXX WHERE id = $delete"); } }
maisumakun

2016/08/16 01:55

無理に一体化せず、そのままでいいと思います。UPDATEとDELETEを共用しようという考えがそもそもの間違いです。
a-_.

2016/08/16 02:15

では、訂正前のコードからどのようなコードすればタイトル通りの処理が実現できるというのでしょうか
Panzer_vor

2016/08/16 02:20

横から失礼いたします。 修正前のコードでも、 各分岐内でMySQL側と発生する通信回数は変わらないので、UPDATEとDELETEを一緒にするメリットがないと思われますよ。
maisumakun

2016/08/16 02:23

複数列に対して同じ更新をかける場合、WHERE id IN (1, 2, 3, 4)のような方法があります。 別件ですが、元のコードではエスケープなどが不足しているので、変なデータをPOSTされれば一撃でSQLインジェクションの被害に遭います。
a-_.

2016/08/16 02:37

KotoriMaturiさんご回答ありがとうございます メリットデメリットでコードを打つというよりかは、本来であれば行う必要はないのでしょうけどやり方が知りたいのでお聞きしました WHERE id INとループ文ではどう処理が異なるのでしょうか
Panzer_vor

2016/08/16 02:51

> a-_.さん 実際にそういうコードを書く機会がなかったので断言はできないですが、 複数クエリをまとめて実行する機能という意味ではmaisumakunさんの掲載リンクが参考になるのではないでしょうか? またINを使ったものとforによるループの違いですが、 これこそ正にデータベースとのアクセス回数に違いがでます。 INリストのパラメタとしてIDリストを引き渡しした場合は、1回の通信でリストに指定したIDに対応するデータを更新・削除できます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問