(-_-)zzz.... このページをアンテナに追加

2005-08-22

[] ADOdbのReplace 16:24  ADOdbのReplaceを含むブックマーク

普通によくある

  1. データがなかったらINSERT
  2. データがあったらUPDATE

を行う為のメソッドとしてADOdbにReplaceメソッドが用意されて*1結構便利。

Replace

使い方もこんな感じでとっつきやすい感じ。

        // 登録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メソッドを使うように統一を考え中。

[] ADOdbのReplaceの問題点 20:33  ADOdbのReplaceの問題点を含むブックマーク

どうやらキーのみを指定すると必ずINSERTにいってデータがあるとキー重複エラーになる模様。

で、ソースを追ってみると adodb-lib.inc.php の _adodb_replace() 関数にたどり着き

中では大幅に略すと以下のようなロジック

  1. キーと値を指定しているとUPDATE文を作成し更新
  2. UPDATE文を発行済かつ条件にマッチする行があれば正常終了
  3. 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で確認した際の話。

*1PEAR::DB等にはあるのかな?