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

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

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

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

PHP

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

Q&A

解決済

4回答

4169閲覧

MYSQL DELETE文が実行されない

harajima

総合スコア15

MySQL

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

PHP

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

0グッド

0クリップ

投稿2018/12/20 09:27

編集2018/12/20 17:12

DELTE文がうまく実行されない

php、mysqlを利用して簡易掲示板のユーザー登録機能を作っています。
そこで今実装したいのが仮登録(本登録フラグがFALSE)のまま1日以上経過したユーザーはデータベース上から削除するというプログラムです。

以下では、まず仮登録のユーザーをセレクトし、その投稿時刻が現在の時間より1日以上離れていれば、そのユーザーのID(ユニークな値)をもとにDELTEする、というような流れのつもりで記述しています。

php

1<?php 2$user = '*************'; 3$password = '********'; 4$dsn = "********************************************************"; 5 6$pdo = new PDO($dsn, $user, $password); 7// if($pdo){ 8// echo "繋げてはいます"; 9// } 10$time_now = date('Y-m-d H:i:s'); 11//今の時間を表示してみる 12//echo $time_now; 13 14//仮登録の人をセレクト 15$sql = "SELECT * FROM user_information WHERE registered = 0"; 16$stmt = $pdo->query($sql); 17// if($stmt){ 18// echo "実行できています"; 19// } 20foreach($stmt as $row) { 21 $time_post = $row["date"]; 22 $key = $row["id"]; 23 echo "ID:".$key." "; 24 $time_post_sec = strtotime($time_post); 25 $time_now_sec = strtotime($time_now); 26 $differences = $time_now_sec - $time_post_sec; 27 //時間差を日という単位まで丸める 28 $differences = gmdate("d",$differences) - 1; //なぜか予定より1多い 29 echo "時間差:".$differences." "; 30 if($differences > 0){ 31 $sql = 'DELETE FROM user_information WHERE id = "$key"'; 32 $stmt = $pdo->query($sql); 33 if($stmt){ 34 echo "期限切れだったので消しました<br/>"; 35 }else{ 36 echo "期限切れだったけど消しませんでした<br/>"; 37 } 38 }else{ 39 echo "仮登録後1日以内<br/>"; 40 } 41 42} 43 44 ?> 45

if文内ではユーザーはきちんと仕分けられ、登録後1日以上経っているユーザーに関しては”期限切れだったので消しました”を出力します。しかし、そこを通っているだけで、実際は消えていません。これはなぜでしょうか?DELETE文の書き方に問題がありますか?
ご教授いただけますと幸いです。

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

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

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

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

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

Orlofsky

2018/12/20 10:39

DELTE → DELETE くらいは直しては?
harajima

2018/12/20 17:11

ご指摘ありがとうございます。修正いたしました
Orlofsky

2018/12/20 21:24

あと2ヶ所あります。
guest

回答4

0

ベストアンサー

$sql = 'DELETE FROM user_information WHERE id = "$key"';

シングルクォートで囲んだ文字列の中では変数が展開されません。
つまり、$keyがそのまま文字列として出力されます。

全体をダブルクォートで囲み、$keyをシングルクォートで囲めばよいかと。

投稿2018/12/20 09:42

dice142

総合スコア5158

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

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

harajima

2018/12/20 17:18

的確なご指摘ありがとうございました。最も早く望んでいた回答をいただけたのでベストアンサーとさせていただきました。
guest

0

これだとidの値が文字列「$key」のものが削除されます。$key変数が展開されるようにsql文を作成してください。

deleteは0件でも正常なので質問に記載の動作になります。

SQL

1 $sql = 'DELETE FROM user_information WHERE id = "$key"'; 2

「期限切れだったので消しました」をechoしている所で、$sqlの内容もechoしてみればなにが起こっているか一発で解ると思います。

投稿2018/12/20 09:49

Y.H.

総合スコア7914

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

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

harajima

2018/12/20 17:14

クオーテーションについて理解が逆になっていました…。 "deleteは0件でも正常"、"$sqlの内容をecho"とても参考になりました。今後にも活かします、ありがとうございました。
guest

0

delete文自体に問題はありませんが、
phpの「文字列内での変数展開」についての理解と、delete結果の確認の仕方に問題があるのではないかと思います。

■phpの「文字列内での変数展開」
文字列内の変数展開は、ダブルコーテションで括られた文字列の中、で行われます。

$sql = 'DELETE FROM user_information WHERE id = "$key"';

では、シングルコーテーションで括られた文字列の中に変数がいますので、展開されません。

実際に実行されているSQLが

DELETE FROM user_information WHERE id = "$key"

になってしまっていると思います。

■deleteの結果の確認方法

delete文は、削除行数に関わらず、SQL的に問題がなければ、実行結果はいつでもtrueです。
例え条件で「削除対象行が0」だとしても、そのSQLが実行できたことには変わりないからですね。

なので、deleteは、SQL実行によって影響を受けた行数を取得した方が良いので、query()ではなくexec()で実行した方が良いかと思いますよ。

投稿2018/12/20 09:49

mix-peach

総合スコア1910

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

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

harajima

2018/12/20 17:17

非常に丁寧な回答ありがとうございました。恐ろしく明快に説明していただき恐縮です。exec()での実行も勉強になりました。ありがとうございました。
guest

0

DELETEを処理するメンテは1日1回で十分。
仮登録されてタイムスタンプ(datetime)に対して、その日の翌々日の0時に24時間以上前の
レコードを削除するメンテプログラムを仕込んでおいてください

仮に12/10のデータは12/12の0時に 12/11 0時以前のデータを削除する処理で削除します。
しかしこれでは実際には24時間を期限にできませんが
実際には仮登録ですから本登録処理の要求があったときに削除をします。

12/10 10:00に仮登録され、12/11 11:00に本登録の要求が来た場合、
要求に対して12/10 11:00以前のデータを削除した上で、本登録処理を走らせます
もし本登録が12/11 9:00にあれば、削除処理に絡まないので処理ができます

投稿2018/12/20 09:39

yambejp

総合スコア114775

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

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

harajima

2018/12/20 17:20

この次にちょうどやろうとしていたことでした。ご丁寧に教えていただき有難うございます、とても参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問