1. ホーム
  2. mysql

[解決済み] MySQL 複数テーブルへのインサート?(データベースの正規化?) [重複]。

2022-05-10 09:28:27

質問

の方法を探してみました。 insert の情報を同じクエリで複数のテーブルから取得する方法を探してみましたが、不可能であることがわかりました。 そこで、私は insert は、単純に複数のクエリ、すなわちを使用することによってそれをしたい。

INSERT INTO users (username, password) VALUES('test', 'test')
INSERT INTO profiles (userid, bio, homepage) VALUES('[id of the user here?]','Hello world!', 'http://www.stackoverflow.com')

しかし、自動インクリメントを行うにはどうすればよいのでしょうか。 id から users を "manual"に変更します。 userid のために profile のテーブルを作成しますか?

どのように解決する?

いいえ、1 つの MySQL コマンドで複数のテーブルに挿入することはできません。しかし、トランザクションを使用することはできます。

BEGIN;
INSERT INTO users (username, password)
  VALUES('test', 'test');
INSERT INTO profiles (userid, bio, homepage) 
  VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com');
COMMIT;

をご覧ください。 LAST_INSERT_ID() を見て、オートインクリメント値を再利用してください。

あなたは " と言いました。 これだけ考えても、まだうまくいきません。単に、生成されたばかりの ID を $var に入れ、その $var をすべての MySQL コマンドに入れることはできないのでしょうか? "

詳しく説明しますと、ここでは3つの可能な方法があります。

  1. 上にあるようなコードで。これは はすべてを MySQL で行っており LAST_INSERT_ID() を 2 番目の ステートメントは自動的に の値になります。 に挿入された の値になります。

    残念ながら、2つ目のステートメント自身がオートインクリメントカラムを持つテーブルに行を挿入すると LAST_INSERT_ID() はテーブル 2 のものに更新され、テーブル 1 のものには更新されません。もし、その後もテーブル1のそれが必要であれば、変数に格納する必要があります。これが方法2、3につながります。

  2. をストックすることになります。 LAST_INSERT_ID() を を MySQL 変数に格納します。

    INSERT ...
    SELECT LAST_INSERT_ID() INTO @mysql_variable_here;
    INSERT INTO table2 (@mysql_variable_here, ...);
    INSERT INTO table3 (@mysql_variable_here, ...);
    
    
  3. を仕入れる予定です。 LAST_INSERT_ID() を php 変数 (またはデータベースに接続できる任意の言語) に格納します。 データベースに接続することができます。 を指定します。)

    • INSERT ...
    • あなたの言語を使って LAST_INSERT_ID() を取得するには、MySQL でそのリテラルステートメントを実行するか、あるいは php の mysql_insert_id() を使用することで、それを行うことができます。
    • INSERT [use your php variable here]

警告

どのような解決方法を選ぶにせよ、何が起こるべきかを決めなければなりません。 クエリ間で実行が中断された場合 (例えば、データベースサーバがクラッシュした場合など)。もしあなたが "some have finished, others not" に耐えられるのであれば、この先は読まないでください。

しかし、「すべてのクエリーが終了するか、または何も終了しないか - あるテーブルの行は必要ないが、他のテーブルの行は一致しない、私のデータベース テーブルは常に一貫していたい」と判断した場合、すべてのステートメントをトランザクションでラップする必要があります。そのために、私は BEGINCOMMIT をここに追加します。