2005-08-22
■[PHP] ADOdbのReplace 
普通によくある
- データがなかったらINSERT
- データがあったらUPDATE
を行う為のメソッドとしてADOdbにReplaceメソッドが用意されて*1結構便利。
使い方もこんな感じでとっつきやすい感じ。
// 登録or更新情報作成
$datas = array('user_id' => $db->qstr($id)
,'user_nm' => $db->qstr($name)
,'comment' => $db->qstr($comment));
// キーカラム情報作成
$keys = array('user_id');
// 追加or更新
$result = $db->Replace('user_mst'
,$datas
,$keys
,false );
$resultは0が異常終了。
注意点として4つ目の引数が$autoQuoteになっていて
trueにしてデータ作成時に自分でqstrしない状態で
0埋めされたIDを渡したら埋めていた0がない条件で検索&登録されるという事。(V4.64で確認)
登録更新系はこのメソッド、検索系はGet〜〜メソッド、削除がExecuteメソッドを使うように統一を考え中。
■[PHP] ADOdbのReplaceの問題点 
どうやらキーのみを指定すると必ずINSERTにいってデータがあるとキー重複エラーになる模様。
で、ソースを追ってみると adodb-lib.inc.php の _adodb_replace() 関数にたどり着き
中では大幅に略すと以下のようなロジックに
- キーと値を指定しているとUPDATE文を作成し更新
- UPDATE文を発行済かつ条件にマッチする行があれば正常終了
- INSERT文発行
INSERT文発行の制限をかけてない、、(ノ∀`)タハー
ということでINSERT文発行前にキーのみの指定だったらその行が存在するかのチェックを追加
adodb-lib.inc.php の _adodb_replace() 関数 90行目付近に以下を追加
if ($uSet && $where) {
$update = "UPDATE $table SET $uSet WHERE $where";
・・・・
}
//Mod:Start キー値のみのReplace対応
if (!$uSet) {
$cnt = $zthis->GetOne("select count(*) from $table where $where");
if ($cnt > 0) return 1; // record already exists
}
//Mod:End キー値のみのReplace対応
// print "<p>Error=".$this->ErrorNo().'<p>';
$first = true;
foreach($fieldArray as $k => $v) {
if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
該当の行、挙動等はV4.64で確認した際の話。
コメントを書く