web-dev-qa-db-fra.com

Comment réinitialiser une incrémentation automatique MySQL en utilisant une valeur MAX d'une autre table?

Je sais que cela ne fonctionnera pas, je l'ai essayé sous diverses formes et j'ai échoué à tout moment. Quelle est la manière la plus simple d'obtenir le résultat suivant?

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

C'est idéal pour les projets d'automatisation. Je vous remercie!

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?
34
ThinkCode

Utilisez un déclaration préparée :

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

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

  DEALLOCATE PREPARE stmt;
36
OMG Ponies

suivant la documentation mysql , cela a fonctionné pour moi dans mysql 5.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;
20
Saeed

Je crée un script de transformation de base de données automatisé pour une nouvelle version de mon application.

Dans une table, j'avais besoin de changer le champ d'incrémentation automatique principal en un champ différent. Étant donné que cette page est apparue plusieurs fois en premier pendant que je recherchais une solution sur Google, voici une solution qui a finalement fonctionné pour moi:

-- 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;
8
user357516

Qui a des problèmes avec PREPARE stmt FROM 'ALTER TABLE XYZ AUTO_INCREMENT =?' can use

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
6
Anurag

Réinitialiser les ID d'incrémentation automatique.

http://community.spiceworks.com/scripts/show/3042-reset-auto-increment-ids

mettre à jour toutes les colonnes d'incrémentation automatique d'une base de données à la valeur la plus petite possible en fonction des valeurs actuelles dans les bases de données. Nous devions le faire après avoir nettoyé une base de données.

Utilisez une instruction préparée dans une procédure stockée:

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');
4
Artistan

Ok les gars. J'ai trouvé une solution pas si intuitive. La meilleure partie est que cela fonctionne!

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);
2
ThinkCode

Personnellement, j'utiliserais probablement un script Shell ou une petite application C #/C++ ou un script PHP/Ruby/Perl pour le faire en 2 requêtes:

  • Saisissez la valeur souhaitée SELECT MAX(ID) FROM ABC;
  • Modifiez le tableau à l'aide de la valeur ALTER TABLE XYZ AUTO_INCREMENT = <insert value retrieved from first query here>

Évidemment, veillez à ce que le nouvel incrément automatique n'entraîne aucun conflit de touches avec les données existantes dans la table XYZ.

1
Andy Shellam

Si vous voulez vraiment faire cela dans MySQL seul, vous pouvez simplement vider la commande alter construite dynamiquement dans un fichier sur le disque, puis l'exécuter.

Ainsi:

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
1
Ike Walker