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

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

ただいまの
回答率

91.35%

  • PHP

    15175questions

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

  • MySQL

    4387questions

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

  • PDO

    273questions

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

【PHP,MySQL,PDO】DELETE,UPDATEだけ実行結果TRUEなのにレコードが更新されない

解決済

回答 3

投稿 2017/12/06 17:40 ・編集 2017/12/07 09:13

  • 評価
  • クリップ 2
  • VIEW 143

hanhunhun

score 37

いつもお世話になっております。

表題の件、動的に発行したクエリ文をPDOで実行するとDELETE,UPDATEのみ実行はされるが該当レコードが更新されない事象が発生しております。

PHP5.6
MySQL5.7
centOS7
nginx

try{
$sql = "DELETE FROM hoge WHERE foo = ? AND bar = ?"; //ここがSELECT or INSERTだと正常に実行され、結果も返ってくる

$arr = array("apple","orange");

$pdsn = "~";//PDO接続情報

$pod_options = array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
);

$pdo = new PDO($pdsn ,$pod_options );

$sth = $pdo->prepare($sql);

$sth->execute($arr);

}catch(PDOExeption $e){
echo $e->getMesseaaaaaaaage;
}

MySQLのユーザーはrootで接続しているので権限周りは問題ない認識です。

わかりにくいかもしれませんがお知恵をお貸しいただけると助かります。

[2017-12-07 9:10 追記]
・上記ソースで全てです。クエリ部分をSELECT文に差し替えた場合は正常に結果が返ってきます。
・INSERTに関しては別の個所に記載されているプログラムが動作し、正常にINSERTされていることを確認しています。
・そのほかの検証としては上記DELETE文をPDO宣言直下で実行してみましたが結果は変わらずtrueの0件で返ってきます。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hanhunhun

    2017/12/07 01:06

    3.executeの戻り値をダンプした際trueが返っているのを確認しています

    キャンセル

  • masaya_ohashi

    2017/12/07 01:23

    提示されたコードで全てですか?削除されている部分はありませんか?INSERTのテストはこのコードのクエリ文だけを差し替えて試したものですか?

    キャンセル

  • hanhunhun

    2017/12/07 09:15

    2.DELETE文のWHERE句に指定してあるカラムはすべてprimary keyで、そのテーブルで指定してある複合キー全てを指定しています。

    キャンセル

回答 3

+2

MySQLの設定でsql_safe_updatesというフラグがあります。このフラグが立っているとき、PRIMARY KEYの指定を含まないUPDATEやDELETEがエラーになります。
http://systemengineer.site/archives/16643664.html

そして、PDOのデフォルト設定ではエラー時にExceptionは発生せず、executeの戻り値を見た上で、PDOStatement::errorInfoで調べる設定になっています。

つまり私が疑っているのは「実際はエラーが起きているが気付いてないのではないか」ということです。

エラーをexceptionで検知するにはこのページの説明のようにsetAttributeかコンストラクタでPDO::ATTR_ERRMODEを変更する必要があります。

で、問題の解決方法ですが、以下の3つがあります。

  • mysqlの設定を変えてsql_safe_updatesフラグを下ろす
  • WHERE句をfoo、barではなくプライマリキーなカラムにする、
  • WHERE句に絶対にTRUEになるプライマリキーの条件を追加する(例:id>0等)

フラグを下ろすのが簡単ですが、セキュリティ(というよりうっかり事故防止)のためにこの方法は出来れば取るべきではありません。
プライマリキーをカラムに入れるのが本当は一番正しいですが、場合によっては条件に合うもの全てに更新をかけたりしたいこともあるでしょう。そんなとき私は最後の方法を取ります。

投稿 2017/12/07 00:51

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/07 09:37

    回答ありがとうございます。
    以下、現状の調査結果です。
    1.sql__safe_updatesはOFFとなっていました。
    2.WHERE句のカラムはそのテーブルのプライマリキー全てを指定しています。

    上記環境でも依然としてUPDATEとDELETEのみ実行OKの結果0件で返ってきます。
    確認方法として以下を行いました。
    1.DELETE処理が実行された直後で処理を殺し、Mysqlのクエリログから該当のDELETE文を取得
    2.そのDELETE文の条件に当てはまるレコードを検索した結果削除されずに残っていました。

    以上です。

    キャンセル

  • 2017/12/08 10:16

    処理を殺し、とありますがphpのexit命令のことですか?

    キャンセル

check解決した方法

+1

みなさん有益な情報をありがとうございます。

結論から言いますとDBとプログラムで文字コードが相違し、WHERE句でうまくマッチングできていなく、結果更新がかからないという初歩的な原因でした。

今回は先入観のせいで文字コードの見直しが出来ていなかったためのバグでした。

ベストアンサーは後学の意も含め選ばせていただきました。

ありがとうございました。また何かあったときはよろしくお願いいたします。

投稿 2017/12/12 11:59

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/12 12:01

    あー…盲点でした。でも私をベストアンサーにする必要はないですよ。「問題」に対する「解決」こそがベストアンサーになるべきです。後から見た人が私のやり方で直ると勘違いしてしまいます。素直に自己解決をベストアンサーにしてください。

    キャンセル

  • 2017/12/12 12:41

    selectはコンソールで行っていたということなんですね。

    キャンセル

+1

COMMITのモードは確認されていますか?
selectやinsertで結果が返ってきて、deleteやupdateでは確定していないということなので、
※insertは追加しようとしている値が返却されているだけだと思う。
commitされていないというのが一番考えられることじゃないでしょうか。

投稿 2017/12/11 15:51

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/11 16:13

    私もコミットしていないことを危惧して「exit」で抜けたりしていないかを確認中です。

    キャンセル

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

ただいまの回答率

91.35%

関連した質問

同じタグがついた質問を見る

  • PHP

    15175questions

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

  • MySQL

    4387questions

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

  • PDO

    273questions

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