1. ホーム
  2. mysql

[解決済み】MySQLのforeachループ

2022-01-25 10:45:05

質問内容

MySQLのUserテーブルの各行を反復処理する必要があります。 以下のような条件で、Userの各反復行に新しい行のAddressを作成する必要があります。

私は3つのテーブルを持っています。

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

User.id_person が NOT NULL で、かつ person.id_address が NULL の場合、Address に新しい行を作成する必要があります。 User.emailと同じemailを持つ行を作成する必要があります。 Userの各行に対してこれを行う必要があります。

MySQLのカーソルを使おうとしましたが、使い方がよくわかりません。

どうすればいいのでしょうか?カーソルを使う代わりに何か他の方法がありますか?

よろしくお願いします。

EDIT: 今気づきましたが、person.id_address を今作成した address' 行の id で更新する必要があります。

どのように解決するのですか?

私が調べたところでは、あなたが提供したフィールドである限り、以下のもので十分だと思います。

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

EDIT (カーソル付き)

カーソルを使えば簡単にできるはずですが、これらの意味するところをよく理解しておくことを強くお勧めします。

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();