6

Ok。つまり、私は次のようなINSERTSELECTを実行しようとしていました。

START TRANSACTION;  
INSERT INTO dbNEW.entity (commonName, surname)  
SELECT namefirst, namelast  
FROM dbOLD.user;  
SET @key = LAST_INSERT_ID();  
INSERT INTO dbNEW.user (userID, entityID, other)  
SELECT user_id, @key, other  
FROM dbOLD.user;  
COMMIT;

もちろん、@ keyは、各挿入から後続の各LAST_INSERT_ID()を返すのではなく、最後の挿入からのIDのみを返します。

基本的に、私は古いUSERテーブルをENTITYとUSERに分割しています。

 dbOLD.user
 +-------------+---------------------+------+-----+------------+----------------+
 | Field       | Type                | Null | Key | Default    | Extra          |
 +-------------+---------------------+------+-----+------------+----------------+
 | user_id     | int(10) unsigned    | NO   | PRI | NULL       | auto_increment |
 | namefirst   | varchar(20)         | NO   |     |            |                |
 | namelast    | varchar(20)         | NO   |     |            |                |
 | other       | varchar(10)         | NO   |     |            |                |
 +-------------+---------------------+------+-----+------------+----------------+


 dbNEW.user
 +-------------+---------------------+------+-----+------------+----------------+
 | Field       | Type                | Null | Key | Default    | Extra          |
 +-------------+---------------------+------+-----+------------+----------------+
 | userID      | int(10) unsigned    | NO   | PRI | NULL       | auto_increment |
 | entityID    | int(10) unsigned    | NO   | MUL | 0          |                |
 | other       | varchar(10)         | NO   |     |            |                |
 +-------------+---------------------+------+-----+------------+----------------+


 dbNEW.entity
 +--------------+---------------------+------+-----+------------+----------------+
 | Field        | Type                | Null | Key | Default    | Extra          |
 +--------------+---------------------+------+-----+------------+----------------+
 | entityID     | int(10) unsigned    | NO   | PRI | NULL       | auto_increment |
 | commonName   | varchar(20)         | NO   |     |            |                |
 | surname      | varchar(20)         | NO   |     |            |                |
 +--------------+---------------------+------+-----+------------+----------------+

なぜ私はこれをしたいのですか?基本的に、住所や電話番号など、「USERS」に共通のフィールドを持つ「STORE」エンティティがあります。したがって、「ENTITY」には、複数の住所(配送、請求、郵送)がなく、複数の電話番号(ファックス、メイン、請求、携帯電話、自宅)がない場合があります。これを実現する方法は他にもありますが、これが解決策です。で終わった。

古いデータベースのSTOREとUSERSは、古いPKを保持し、追加のENTITYfkを取得する必要があります。ダンプを作成して手動で編集せずにこれを行うにはどうすればよいですか?

4

2 に答える 2

5

最後のクエリには、これを使用します

INSERT INTO dbNEW.`user` (userID, entityID, other)  
SELECT user_id, entityID, other
FROM
(
    SELECT user_id, @key + @rn entityID, other, @rn := @rn + 1
    FROM (select @rn:=0) x, dbOLD.`user`
    order by user_id
) y;

MySQLのLAST_INSERT_ID()は、最後のIDであるSQL ServerのSCOPE_IDENTITY()とは異なり、バッチで作成された最初のIDです。これは最初の行なので、変数@rnを使用して各行をインクリメントaddition=0し、最初の行から開始します。

于 2011-02-20T03:49:13.923 に答える
1

この場合、古いユーザーをループして2つの個別の挿入を行うカーソルベースのソリューションが必要になる場合があります。これは一括挿入を行いませんが、行を手動で更新するよりも優れています。

DELIMITER $$
DROP PROCEDURE IF EXISTS MigrateUsers $$
CREATE PROCEDURE MigrateUsers ()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE user_id INT;
  DECLARE namefirst VARCHAR(20);
  DECLARE namelast VARCHAR(20);
  DECLARE other VARCHAR(10);
  DECLARE lid INT;
  /*Cursor looping over old users*/
  DECLARE cur CURSOR FOR
    SELECT user_id, namefirst, namelast, other
    FROM dbOLD.user;

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  OPEN cur;
  START TRANSACTION; 
  read_loop: LOOP
    FETCH cur INTO user_id, namefirst, namelast, other;
    IF done THEN
      LEAVE read_loop;
    END IF;
    /*Insert entity part*/
    INSERT INTO dbNEW.entity (commonName, surname)
      VALUES (namefirst, namelast);
    SET lid = LAST_INSERT_ID();
    /*Insert user part*/
    INSERT INTO dbNEW.user (userID, entityID, other)  
    VALUES (user_id, lid, other);

  END LOOP;
  COMMIT;
  CLOSE cur;
END$$
DELIMITER ;

手順カーソルに関するドキュメントを読むことをお勧めします

于 2011-02-20T00:41:12.220 に答える