0

itemId(item.id) と tagId(tag.id) をマップするテーブルがあります。

新しい行を挿入する必要があるクエリを作成していますが、itemId と tagId の両方にまだエントリがない場合のみです。これを行う最善の方法は何ですか?

これは、既存の一致をまだチェックしていない現在のクエリです。

// create tag-item maps
$sql = 'INSERT INTO item_tag
      SELECT :itemId AS iid, tag.id AS tid
      FROM tag
      WHERE tag.name=:name';
try{
  $stmt = $db->dbh->prepare($sql);
  for($i = 0; $i < $count; $i++) {
    $data = array(':itemId' => $itemId, ':name' => $tags[$i]);
    $result = $stmt->execute($data);
    if($result !== false) {
      // Do nothing
    }else {
      return false;
    }
  }
  return true;
}catch(PDOException $e) {
 logit($e->getMessage());
 return false;
}
4

1 に答える 1

1

UNIQUE制約は理想的な解決策であり、ドキュメントによると、MyISAMエンジンはそれらをサポートしています。

ALTER TABLE item_tag ADD CONSTRAINT item_tag_iid_tid_uq UNIQUE (iid, tid);

次にINSERT、重複する ( iid, tid) ペアを追加しようとするとスローされ、コードで処理できますcatch

制約を行いたくない場合は、UNIQUE代わりに「存在」チェックをINSERTクエリに追加できます。

INSERT INTO item_tag
  SELECT :itemId AS iid, tag.id AS tid
  FROM tag
  WHERE tag.name=:name' AND NOT EXISTS (
    SELECT * FROM item_tag WHERE iid=:itemId AND tid=tag.id)

独自の異なる名前のテーブルを使用してこれをテストしたので、テーブル/列名に正しく「翻訳」したことを願っています。

于 2013-03-28T17:01:24.127 に答える