多対多の関係を処理するために3つのテーブル構造を使用しています。私は人のリストを持つテーブルと項目のリストを持つテーブルを持っています。時々、複数の人が同じアイテムを持っていると私は、次の表の構造を設定して、時には倍数項目が同じ人物にリンクされています:アイテムがすでに存在するときに中間テーブルを更新する際に問題が発生する
CREATE TABLE people (
id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
fname varchar(128) NOT NULL,
lname varchar(128) NOT NULL,
);
CREATE TABLE items (
id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
name varchar(128) NOT NULL UNIQUE,
);
UNIQUEを繰り返すから項目名を防ぐことができます。
CREATE TABLE people_items (
pid int(11) NOT NULL,
iid int(11) NOT NULL,
FOREIGN KEY (pid) REFERENCES people(id)
ON UPDATE CASCADE
ON DELETE CASCADE
FOREIGN KEY (iid) REFERENCES items(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
これにより、複数のアイテムを複数のユーザーにリンクすることができます。また、中間テーブルから不要なレコードを削除することもできます。
新しい項目が入力されている限り、すべて正常に動作しますが、既存の項目を入力すると、中間表は更新されません。ただし、people表は更新されません。私もエラーはありません。
項目は、コンマで区切られたテキストエントリで、分解され、下のケースは$items
になります。新しいIDは、次が実行されて返送された場合
for ($i=0;$i<count($items);$i++){
$sql="INSERT IGNORE INTO items (name) VALUES (?);";
$stmt=$conn->prepare($sql);
$stmt->bind_param('s',$items[$i]);
$stmt->execute();
$itemid=$stmt->insert_id;
:
まず私は、新しいアイテムを挿入し、IDを取得
if ($itemid){
$sql="INSERT INTO people_items (pid,iid) VALUES (?,?);";
$stmt=$conn->prepare($sql);
$stmt->bind_param('ii',$peopleid,$itemid);//the $peopleid is acquired the same way that the $itemid is acquired above
$stmt->execute();
}
ここまでは、すべてがうまく動作します。現時点では、既存のアイテムが既にアイテムテーブルにある場合は、中間テーブルが更新されない場所です。ただし、peopleテーブルはうまく更新され、itemsテーブルにはアイテムが既に含まれているため、更新する必要はありません。
ここでは、中間テーブルを更新する2つの異なる方法を試しました。
最初に、私はselectとinsertのクエリを別々にしました。ここで
elseif(!$itemid){
$sql="SELECT id,name FROM items WHERE name=?;";
$stmt=$conn->prepare($sql);
$stmt->bind_param('s',$items[$i]);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($iid,$name);
$stmt->fetch();
$sql="INSERT INTO people_items (pid,iid) VALUES (?,?);";
$stmt=$conn->prepare($sql);
$stmt->bind_param('ii',$pid,$iid);
$stmt->execute();
}
も中間テーブルを更新しません、私の別のアプローチである:
elseif(!$itemid){
$sql="INSERT INTO people_items (pid, iid) SELECT id,name FROM items WHERE name IN (?);";
$stmt=$conn->prepare($sql);
$stmt->bind_param('s',$items[$i]);
$stmt->execute();
}
は私が間違って何をしているのですか?