web-dev-qa-db-ja.com

MySQL foreachループ

MySQLのテーブルUserの各行を繰り返す必要があります。以下に説明するいくつかの条件を使用して、ユーザーの各反復ごとに新しい行アドレスを作成する必要があります。

3つのテーブルがあります。

User: id, stuff, id_person, email
Person: id, stuff, id_address
Address: id, email

User.id_personがNULLでなく、そのperson.id_address IS NULLの場合、Addressに新しい行を作成する必要があります。User.emailと同じメールで行を作成する必要があります。ユーザーの各行に対してそれを行う必要があります。

MySQLカーソルを使用しようとしましたが、それらの使用方法がよくわかりません。

どうやってやるの?そのためにカーソルを使用する代わりに他の方法はありますか?

前もって感謝します。

編集:私は今作成したアドレスの行のIDでperson.id_addressも更新する必要があることを認識しました。

4
Daniel

私が収集できるものから、フィールドがあなたが提供したものである限り、以下で十分です。

INSERT INTO Address (email)
  SELECT User.email
    FROM User JOIN person ON User.id_person = person.id
   WHERE person.id_address IS NULL
;

編集(カーソルあり)

これはカーソルを使用するとかなり簡単なはずですが、これらとその影響について理解することを強くお勧めします。

DROP PROCEDURE IF EXISTS _tmp_update_address;
DELIMITER $$
CREATE PROCEDURE _tmp_update_address()
BEGIN
   DECLARE cursor_List_isdone BOOLEAN DEFAULT FALSE;
   DECLARE cur_userId, cur_personId INT;
   DECLARE cur_email VARCHAR(250) DEFAULT '';

   DECLARE cursor_List CURSOR FOR 
      SELECT User.id, person.id_address, User.email
      FROM User JOIN person ON User.id_person = person.id
      WHERE person.id_address IS NULL
    ;

   DECLARE CONTINUE HANDLER FOR NOT FOUND SET cursor_List_isdone = TRUE;

   OPEN cursor_List;

   loop_List: LOOP
      FETCH cursor_List INTO cur_userId, cur_personId, cur_email;
      IF cursor_List_isdone THEN
         LEAVE loop_List;
      END IF;

      INSERT INTO Address (email) VALUES (cur_email);
      UPDATE person SET person.id_address = LAST_INSERT_ID()
         WHERE person.id = cur_personId;

   END LOOP loop_List;

   CLOSE cursor_List;
END

$$

DELIMITER ;

CALL _tmp_update_address();
9
Napoli

このためにカーソルを使用したくありません。あなたの説明に基づいて:

insert into address (address)
    select u.email
    from user u join
         person p
         on u.id_person = p.id;
1
Gordon Linoff