質問: $pdo->query($sql); ``` 挙動としては、削除が完全に終わってから挿入する事を想定しています。 今現在、これを実行すると正しく動作しているように思えるのですが、レコード量が膨大になるとまた違うものなのでしょうか? 「;」で区切って複数のSQLを実行させる場合、そのふたつは同期処理なのでしょうか? また、2つのSQL文を両方実行する方法が、これくらいしか見つけきれなかったのでこうしたのですが、他に良い方法があれば教えていただければ幸いです。 よろしくお願いいたします。
回答: 複数のSQLを一連の操作(1つの塊)として扱いたい場合、トランザクションを用いるのが良いかと思います。 1. トランザクション開始 2. SQL実行 3. SQL実行 4. コミット(またはロールバック) トランザクション開始以降のSQL実行は、「4. コミット」されることで実際に結果が確定されます。 (「ロールバック」するとなかったことにされる) * トランザクションおよび自動コミット * PHP + PDO + MySQL のトランザクション制御方法まとめ コメントを受けての追記 4/23 質問の意図を読み違えて、混乱させてしまったかもしれません。 > > 挙動としては、削除が完全に終わってから挿入する事を想定しています。 > > 今現在、これを実行すると正しく動作しているように思えるのですが、レコード量が膨大になるとまた違うものなのでしょうか? > > > この点については、SQLは順番に実行されるのでDELETE文実行完了後、INSERT文が実行されることになります。 ただし、システム開発においてはエラー時の処理も考慮し、SELECT文以外のSQL実行時にはトランザクションを利用することが多いかと思います。そのため、トランザクションの利用を検討されることをおすすめします。 また、`;`の利用以外でのSQLの複数実行は以下のように実装できます。 (変数名(sql1,sql2)があまりよろしくないですが、実装イメージとしてご確認ください) 例として、DELETE文とINSERT文が一塊りとなるよう、トランザクションを使っています。 ``` // トランザクション開始 $pdo->beginTransaction(); try { // DELETE実行 $sql1 = "DELETE FROM datatable WHERE hoge <= 2" $stmt = $pdo->query($sql1); // INSERT実行 $sql2 = "INSERT INTO datatable(id,hoge) VALUES(1,3)" $stmt = $pdo->query($sql2); // DELETE文とINSERT文が正常に実行できた場合は // コミット $pdo->commit(); } catch (PDOException $e) { // SQL実行時にエラーが発生した場合は // ロールバック $pdo->rollback(); // エラー処理を記述(ログ出力とか、throw e;とか) } ```