web-dev-qa-db-ja.com

多対多の関係のジャンクションテーブルに値を挿入する方法は?

データベースに3つのテーブルがあります。

 trips(trip_id(pk), trip_name(unique), user_id(fk))

 places(place_id(pk), place_name(unique))

 trips_places_asc(trip_id(fk), place_id(fk))

多くの旅行には多くの場所があるため、上記のように1つのジャンクションテーブルがあります。

ユーザーが旅行に場所を挿入すると、その場所はplacesテーブルに追加され、旅行はtrips_places_ascテーブル内の場所に関連付けられます。

したがって、次のようなクエリを作成するとします。

INSERT INTO places (place_name)
VALUES ('XYZ')

INSERT INTO trips (trip_name)
VALUES ('MyTrip')

次に、trip_idおよびplace_idをJunctionまたはAssociationテーブルtrips_places_ascに格納する方法を教えてください。 2つのクエリを実行する必要がありますか?

6
Fenil

新しい場所と旅行を保存するアクションのatomicityと、その2つの間の交差点を維持したいとします。 MySQLでは、これを_START TRANSACTION_/COMMITトランザクションラッパーで行います。

MySQL関数LAST_INSERT_ID()(SQL Server変数_@@IDENTITY_に類似した documentation を参照)を使用して、割り当てられた最新の自動インクリメント値の値を取得します。

placetripを追加し、2つを一度に関連付けるには、次のようなコードを記述します。

_START TRANSACTION

DECLARE placeKey int

INSERT INTO places (place_name)
VALUES ('XYZ')

SET placeKey = LAST_INSERT_ID()

DECLARE tripKey int

INSERT INTO trips (trip_name)
VALUES ('MyTrip')

SET tripKey = LAST_INSERT_ID()

INSERT INTO trips_places_asc(trip_id, place_id)
VALUES (tripKey, placeKey)

COMMIT
_

上記にエラー処理を追加する必要があります。途中でエラーが発生した場合は、ROLLBACKコマンドを使用して、部分的に完了した作業を元に戻します。

また、LAST_INSERT_ID()を読んで、それがどのように機能するかを確認してください。単一の挿入ステートメントで複数の行を挿入する場合など、場合によっては望ましくない結果が生じることがあります。

7
Joel Brown