データ更新で、レコードがあれば update,
無ければ insert というロジックは、よくあると思います。
このとき、両方のテストをしなきゃいけないのが面倒です。
insert が正常でも、update にバグがあるかもしれないからです。
//レコードが無ければ insert
if ( $exist == false ) {
$sql = "insert into 社員マスタ ( ShainNo, Name, Address, Tel ) values ( $ShainNo, '$Name', '$Address', '$Tel' )";
//レコードがあれば update
} else {
$sql = "update 社員マスタ set Name = '$Name', Address = '$Address', Tel = '$Tel' where ShainNo = $ShainNo";
}
//ホントはプリペアドステートメントにしてね
$dbh->exec($sql);
でも、本記事の最後に述べる**「ズボラ方式」**にすると、
テスト工数も減らせるし、楽です。
正規のコーディングの場合
例えば「社員マスタ」の更新なら、
社員番号 / 名前 / 住所 / 電話番号 ・・・ の項目を、
1個ずつ、問題なく格納されるかをチェックします。
まず insert のテストをします。問題なければ update のテストですが、
同じ値でそのまま update するのはダメです。
insert で登録した値とは 別の値で update します。
例えば、[山田] で insert したら、
[山田2] で update して、確実に update したかをチェックします。
これをしないと、
「しまった! update で住所だけ更新がモレてた!」
と後になって気付くことも ありえます。
仮に、テーブル定義から自動でSQLを生成する
O/Rマッパー?(←ゴメン よく知らないの)があれば
コーディングもテストも楽ですが、そんなものも無く、
SQLを直接ゴリゴリ書く会社も未だあります。
以下は、そんな会社のプログラマーのための、
「ズボラ方式」の紹介です。
ズボラ方式
insert では、一度に全カラムを登録するのではなく、
主キーのみ登録(insert)して、直後に他のカラムを update します。
「社員マスタ」の場合、名前や住所は空白のまま、
まず主キーの社員番号のみ 値を設定して insert します。
そして直後に、名前や住所に値を設定して update します。
(最初から update の場合は、update の処理のみ おこないます。)
//レコードが無ければ 主キーのみ insert
if ( $exist == false ) {
$sql = "insert into 社員マスタ ( ShainNo ) values ( $ShainNo )";
$dbh->exec($sql);
}
//レコードの有無にかかわらず update
$sql = "update 社員マスタ set Name = '$Name', Address = '$Address', Tel = '$Tel' where ShainNo = $ShainNo";
$dbh->exec($sql);
//しつこいけどプリペアドステートメントでね
ズボラ方式の利点は、insert のコーディングとテスト工数を
削減できることにあります。
insert と update のロジックが ほぼ同じだからです。
問題点?
●insert のときは、insert と update で2回アクセスが発生する。
頻繁に更新するテーブルなら1回のアクセスに抑えるべきですが、
マスタ登録のように たまに更新する程度なら、
2回アクセスでも問題ないと思います。
●ほんの一瞬だが、名前や住所が空白のレコードが存在することになる。
もし気になるなら、insert ~ update をトランザクションにすることで、
空白のレコードが 他のユーザに見えないようにできます。
●別のズボラ方法として、delete 後 insert してもいい?( update 省略のため )
これは・・・、なるべく やめましょう。
何となくですが。