39

私はこれがうまくいかないことを知っています。いろいろ試してみましたが、いつも失敗しました。次の結果を達成するための最も簡単な方法は何ですか?

ALTER TABLE XYZ AUTO_INCREMENT = (select max(ID) from ABC);

これは自動化プロジェクトに最適です。

SELECT @max := (max(ID)+1) from ABC;        -> This works!
select ID from ABC where ID = (@max-1);     -> This works!
ALTER TABLE XYZ AUTO_INCREMENT = (@max+1);  -> This fails :( Why?
4

8 に答える 8

37

プリペアドステートメントを使用します。

  SELECT @max := MAX(ID)+ 1 FROM ABC;

  PREPARE stmt FROM 'ALTER TABLE ABC AUTO_INCREMENT = ?';
  EXECUTE stmt USING @max;

  DEALLOCATE PREPARE stmt;
于 2010-03-09T19:13:02.153 に答える
29

MySQLのドキュメントに従って、これはMySQL5.7で機能しました。

SET @m = (SELECT MAX(id) + 1 FROM ABC);
SET @s = CONCAT('ALTER TABLE XYZ AUTO_INCREMENT=', @m);
PREPARE stmt1 FROM @s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
于 2017-01-04T14:57:29.843 に答える
11

PREPARE stmt FROM'ALTER TABLE XYZ AUTO_INCREMENT =?'で問題が発生している人は誰でも 使える:

CREATE PROCEDURE reset_xyz_autoincrement
BEGIN
      SELECT @max := MAX(ID)+ 1 FROM ABC;
      set @alter_statement = concat('ALTER TABLE temp_job_version AUTO_INCREMENT = ', @max);
      PREPARE stmt FROM @alter_statement;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;
END
于 2013-07-12T14:24:04.583 に答える
9

新しいバージョンのアプリケーション用に自動化されたデータベース変換スクリプトを作成しています。

1つのテーブルで、プライマリ自動インクリメントフィールドを別のフィールドに変更する必要がありました。このページは、私がその解決策をグーグルで検索しているときに最初に何度も表示されたので、最終的に私のために働いた解決策は次のとおりです。

-- Build a new ID field from entry_id, make it primary and fix the auto_increment for it:
ALTER TABLE  `entries` ADD  `id` INT UNSIGNED NOT NULL FIRST;
UPDATE entries SET id = entry_id;
ALTER TABLE  `entries` ADD PRIMARY KEY (  `id` );

-- ...the tricky part of it:
select @ai := (select max(entry_id)+1 from entries);
set @qry = concat('alter table entries auto_increment=',@ai);
prepare stmt from @qry; execute stmt;

-- ...And now it's possible to switch on the auto_increment:
ALTER TABLE  `entries` CHANGE  `id`  `id` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT;
于 2010-06-03T13:47:45.633 に答える
5

自動インクリメントIDをリセットします。

自動インクリメントIDをリセット

データベース内のすべての自動インクリメント列を、データベース内の現在の値に基づいて可能な限り最小の値に更新します。データベースをクリーンアップした後、これを行う必要がありました。

ストアドプロシージャ内でプリペアドステートメントを使用します。

drop PROCEDURE if exists reset_autoincrement;
DELIMITER //
CREATE PROCEDURE reset_autoincrement (IN schemaName varchar(255))
 BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE o_name VARCHAR(255);
    DECLARE o_table VARCHAR(255);
    DECLARE cur1 CURSOR FOR SELECT COLUMN_NAME, TABLE_NAME FROM information_schema.`COLUMNS` WHERE extra LIKE '%auto_increment%' and table_schema=schemaName;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN cur1;
    read_loop: LOOP
     FETCH cur1 INTO o_name, o_table;

     IF done THEN
       LEAVE read_loop;
     END IF;

  set @qry1 = concat('SELECT MAX(`',o_name,'`) + 1 as autoincrement FROM `',o_table,'` INTO @ai');
  PREPARE stmt1 FROM @qry1;
  EXECUTE stmt1;

  IF @ai IS NOT NULL THEN
      SELECT  o_name, o_table;
   select @qry1;
   select @ai;
   set @qry2 = concat('ALTER TABLE `',o_table,'` AUTO_INCREMENT = ', @ai);
   select @qry2;
   PREPARE stmt2 FROM @qry2;
   EXECUTE stmt2;
  END IF;

    END LOOP;

    CLOSE cur1;
 END //
DELIMITER ;


call reset_autoincrement('my_schema_name');
于 2015-02-19T20:45:53.347 に答える
2

個人的には、シェルスクリプト、小さなC#/ C ++アプリケーション、またはPHP / Ruby / Perlスクリプトを使用して、2つのクエリでこれを実行します。

  • 必要な値を取得しますSELECT MAX(ID) FROM ABC;
  • 値を使用してテーブルを変更しますALTER TABLE XYZ AUTO_INCREMENT = <insert value retrieved from first query here>

XYZ明らかに、新しい自動インクリメントによってテーブル内の既存のデータとキーが衝突しないように注意してください。

于 2010-03-09T16:52:51.227 に答える
1

みんなわかりました。私はそれほど直感的ではない解決策を思いついた。最良の部分はそれが機能することです!

SELECT @max := max(ID) from ABC;       
ALTER TABLE XYZ AUTO_INCREMENT = 1;
ALTER TABLE XYZ ADD column ID INTEGER primary key auto_increment;
UPDATE XYZ SET ContactID = (ContactID + @max);
于 2010-03-09T17:30:30.137 に答える
1

本当にMySQLだけでこれを実行したい場合は、動的に構築された変更コマンドをディスク上のファイルにダンプしてから実行することができます。

そのようです:

select concat('ALTER TABLE XYZ AUTO_INCREMENT = ',max(ID)+1,';') as alter_stmt
into outfile '/tmp/alter_xyz_auto_increment.sql'
from ABC;

\. /tmp/alter_xyz_auto_increment.sql
于 2010-03-09T17:36:10.157 に答える