- 締切済み
UPDATE文
社員番号(user_id)とパスワードを入力するログイン機能を持ち、ログインした社員番号の出勤時間と退勤時間を記録するようなシステムを作っています。 ログインしている社員の時刻だけ(出勤or退勤)を修正する場合、以下のUPDATE文をどのように修正すればいいでしょうか? 'UPDATE timecard SET begin = ?'; テーブルの構造は以下の通りです。 (timecardテーブル :id、 begin、 finish 、date ) (userテーブル :user_id、user_name、password)
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- AsarKingChang
- ベストアンサー率46% (3467/7474)
> finish.phpは > INSERTとWHEREを組み合わせるイメージで合っていますか? 違います!。 UPDATE + WHEREで既存のレコードの、終了時刻側を操作です。 https://www.dbonline.jp/mysql/insert/index7.html お勧めは、カラムに当日を表す数字を一つ埋め込んで置き、 その範囲なら当日とみなすような方式がよいですね。 例えば、0:15(次の日になってる・・・)しかし、 何時までは、「前の日の打刻だよ」のような、イメージ。 それに対してユニークを設定すると、面白い現象が起きます。 (同じ日の打刻を1度しかできない!という制限を書けてしまう!。 なので、初めては、「普通に打刻」2度目は更新しか受け付けなくすることで) INSERT...開始打刻=now() ON DUPLICATE 終了時刻=now() https://dev.mysql.com/doc/refman/5.6/ja/insert-on-duplicate.html 1つのSQL命令で、今日の打刻が「なければ」BEGIN 「すでにあれば、FINISH」に打刻できちゃうんですよ。 ただ、この方法だと2回目以降に、FINISHの書き換えができちゃうので、 BEGINとFINISHが「まだ打刻されていない物」というAND条件をつければ、 パーフェクトかな!
- AsarKingChang
- ベストアンサー率46% (3467/7474)
ですよね。 if (isset($_SESSION['user']) === TRUE) { $user_id = $_SESSION['user']['user_id']; $user_name = $_SESSION['user']['user_name']; } でしたら、 この直後に、 select * from user where user_id=..$user_id and...で そのユーザーのデータをPHP内に そのセッションだけ取り込んでしまうスタイルが多いと思います。 で、取り込んだデータが例えば $user_dataだとしたら、 $user_data['id'] これを維持したまま、timecardに対しても select * from timecard where user_id=$user_data['id']; 的な流れ。 ここで、パニックにならないようにするために、 user::idが本当のユーザーIDであり user::user_idはあくまでフロント(ユーザーが操作するためののID) の2つの考えが混在している事にご注意を! とすれば・・ $user_name = $_SESSION['user']['user_name']; これいらない。 だって、DBに入っているので、 $user_data['user_name'] でDBから取り出したデータの方が正確です。 (クッキーなんかに入れてたら、改ざんされ放題ですから。 セッションも同様) 後は、必要な情報がそろったのではないかな?という 印象ですね。 という事で、残りは「つくるぜ!」がメインですね! 暇なら、付き合ってもいいんですが^^ 知っての通りこのサイトは、個人間のやり取りは出来ないので^^ 見守るのがやっと・・・かな!ってね
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>ログインしているユーザーの時刻情報のみを取得するには、以下のSQL文にJOIN userを追加すればいいですか? そもそもの、一つとして「ログイン」とはなんでしょう? もちろん言葉としてのログインはわかりますが。 何をもって、ログイン中とするか?って問題はあるかと思います。 そもそも、ログインログアウトは、まだ考慮されていない 構造なので。 $sql = 'SELECT begin, finish, date FROM timecard であれば、 その後ろに where id=(select id from user where= ユーザーを識別できる物) と、2段クエリにしてしまえば1発ですが。 大抵PHPでつくるときは、 そもそも以前に、クッキーの値が正当なのか?という チェックをすると思います。 なので、 select * from user where= ユーザーを識別できる物) などで、すでに、 user::idを入手済みのコードになりやすいはずです。 そこで、レスポンスがないなら「不正なユーザーリクエスト」 と判断するなど。 後はそれを利用して以後の処理を行う! という感じの方が、良いかと思います。
補足
回答ありがとうございます。ログインしたら、出勤打刻のページ(begin.php)に遷移します。 begin.phpに以下のように記述して、セッションに保存されているか確認します。 // 最初にログインしているかをチェック if (isset($_SESSION['user']) === TRUE) { $user_id = $_SESSION['user']['user_id']; $user_name = $_SESSION['user']['user_name']; }
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>今phpmyadminを確認したら、userテーブルのuser_idは1~3だけでしたが、timecardテーブルのtimecard_idは1~58ありました。timecardテーブルを初期化した方がいいですか? https://www.dbonline.jp/mysql/insert/index12.html 消したいならこれでもいいですし。 delete文で消してもいいですが。 (TRUNCATEとDELETEの違いについて、 deleteは、今登録されている物が消えるだけで、 AI値などはそのままです) ↑ここから先は、好みにはなるんですが。 だからPDOを、私らは使わないんです。 生でMySQLを使うと、 use XXX;だけでDBそのものを切り替えながら動かせます。 なので、 timecard:本番用のテーブルとカラムが入る。 timecard_dev:本番用と全く同じテーブルとカラムが入る。 として、テストはDEV(デベロップメントの略) で、動作確認をして動作したソース類だけを timecardデータベース(テーブル名ではない) で動作させるべく、useで切り替えている感じです。 いつかプロジェクトが大きくなり、人が増えたら、 誰かが開発中のソースがいきなり本番を ぶっ壊す??なんてのも、うんざりしますからね!
補足
ログインしているユーザーの時刻情報のみを取得するには、以下のSQL文にJOIN userを追加すればいいですか? $sql = 'SELECT begin, finish, date FROM timecard';
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>回答ありがとうございます。userテーブルのuser_idとtimecardテーブルのidが一致すればいいということでしょうか? んま、そうですね。 一致するというより、userが、timecardを打刻するわけなので、 timecard->userの位置関係を持てば! パーフェクトでしょう!。 (当然、例えばやめた社員がいたとしても、 user側のテーブルに「辞めた!」カラムを1個追加するだけで、 データはそのままに、管理できますからね!) また、自分の過去の打刻データ? というときも、 user::idを拾えばいいだけなので、以後の流れが 全部スムーズです。 最初の構造だと、user_nameそのものが、 timecardに入っていたので、無駄に長かったですので。 今のやり方でいいとは思いますよ!。
補足
今phpmyadminを確認したら、userテーブルのuser_idは1~3だけでしたが、timecardテーブルのtimecard_idは1~58ありました。timecardテーブルを初期化した方がいいですか?
- AsarKingChang
- ベストアンサー率46% (3467/7474)
SET begin = ?'; 素直にbegin=now() 誰のを書き換えるか?を付けないと全員のが書き換わるので where id=? その値が、userテーブルのuser_idという感じです。 なので、 (userテーブル :user_id、user_name、password) ここの戦闘は、user_idではなく、idの方が望ましく もし、ユーザーに固有のユーザーIDを与えたいなら、 (userテーブル :id、user_id、user_name、password) として、idはAUTO_INCLIMENTの自動生成での 値を使うのが、よろしいかと! なので、 (timecardテーブル :id、 begin、 finish 、date ) こっちも、 (timecardテーブル :id、timecard_id、begin、 finish 、date ) などにして、timecard_idは、ひとまず vchar:256あたりで初期化して、INSERTにてUUID()などを 入れておけば、ユニーク(かぶらない物)になるので、 それでOKでしょう。 なんで、IDが2個になるの???ってのは、 外に「MySQLが管理している生のIDを出さないため」です。 自動生成のIDは、自動なので、追加するごとにどんどん 値が増えるので、管理者がいじって変更したい?って時、 結局自動になってしまって、後々面倒なんです。 だから、値固有の別のユニークを生成すれば、 そのキーで外部のPHPなどでのAPI動作時 物理DB内の主IDを晒さなくてもすむ!という理屈です。 つまり、何番でも動作し+絶対に同一の1つのレコードを 参照する!のが目的です。 もし、 2か所に同じシステムがあった時、、 AサーバーにIDが、1,2,3 BサーバーにIDが、1,2,3,4 これを1本化して!っていわれたら。無理になるでしょ? ってことです。
補足
回答ありがとうございます。userテーブルのuser_idとtimecardテーブルのidが一致すればいいということでしょうか?
補足
9割くらいは完成しました。出勤用の画面(begin.php)と退勤用の画面(finish.php)を別々にしているので、「出勤時間を打刻した日と同じ日に退勤時間を打刻する」にはどうすればいいでしょうか? begin.phpの方は $sql='INSERT INTO timecard(timecard_id, begin, date) VALUES(?, ?, ?)'; で問題ないと思いますが、 finish.phpは INSERTとWHEREを組み合わせるイメージで合っていますか?