2010-03-09 10 views
25

So che questo non funzionerà, l'ho provato in varie forme e ha fallito tutte le volte. Qual è il modo più semplice per ottenere il seguente risultato?Come resettare un AutoIncrement MySQL usando un valore MAX da un'altra tabella?

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

Questo è ottimo per i progetti di automazione. Grazie!

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? 

risposta

28

Utilizzare un Prepared Statement:

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

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

    DEALLOCATE PREPARE stmt; 
+0

Sembra una risposta abbastanza solida per la mia domanda! Grazie! – ThinkCode

+9

'PREPARA stmt FROM 'ALTER TABLE XYZ AUTO_INCREMENT =?'' genera un errore per me :( – bor

+0

@ T30 qual è il tuo errore? – Beetle

1

Personalmente probabilmente sarei utilizzare sia uno script di shell o un'applicazione po 'C#/C++ o uno script PHP/Rubino/Perl per fare questo in 2 domande:

  • Afferra il valore che si vuole SELECT MAX(ID) FROM ABC;
  • modificare la tabella utilizzando il valore ALTER TABLE XYZ AUTO_INCREMENT = <insert value retrieved from first query here>

Ovviamente facendo attenzione che il nuovo incremento automatico non causerà alcun scontri chiave con i dati esistenti nella tabella XYZ.

+0

Ho pensato che possa essere fatto facilmente utilizzando solo le query MySQL. Sembra che sia sfortunato. Qualsiasi altra soluzione che utilizza solo MySQL - usando le variabili in MySQL? Voglio eseguire una serie di query in un file .sql anziché in script di shell e script Perl/Python. Grazie per la risposta. – ThinkCode

2

Ok ragazzi. Ho trovato una soluzione non così intuitiva. La parte migliore è che funziona!

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); 
+0

Da dove proviene ContactID? – T30

0

Se davvero si vuole fare questo in MySQL da solo, si può semplicemente scaricare il comando alter costruita dinamicamente in un file su disco e quindi eseguirlo.

Come così:

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 
+0

Grazie per la risposta. Questa è una soluzione interessante! Potrebbe essere un lavoro extra per la mia situazione. – ThinkCode

5

Sto creando uno script automatico del database di trasformazione per una nuova versione della mia applicazione.

In una tabella, avevo bisogno di cambiare il campo autoincremento primario in un campo diverso. Dal momento che questa pagina si avvicinò prime molte volte mentre Ho cercato su google una soluzione per esso, ecco una soluzione che alla fine ha funzionato per me:

-- 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; 
+0

questo effettivamente funziona in mys ql 5.5 – shigeta

7

che sta avendo problemi con PREPARARE stmt DA 'ALTER TABLE XYZ AUTO_INCREMENT =?' può utilizzare

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 
+0

Ho avuto grandi speranze per questo, ma ottengo questo errore: # 1064 - Hai un errore nella sintassi SQL; controlla il manuale che corrisponde alla versione del tuo server MariaDB per la sintassi corretta da usare vicino a 'INIZIA SELECT @max: = MAX (id) + 1 FROM test' alla riga 2 – kloddant

3

Ripristinare gli ID di incremento automatico.

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

aggiornamento tutte le colonne incremento automatico in un database per il valore più piccolo possibile in base a valori correnti nei database. Avevamo bisogno di fare questo dopo aver pulito un database.

Utilizzare una dichiarazione preparata all'interno di una stored procedure:

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'); 
6

seguente the mysql docs, questo ha lavorato per me in 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; 
0

io sono solo un dilettante, ma ho un suggerimento :-) Se si riempie la vostra intera tabella con i nuovi dati, si può semplicemente utilizzare prima del riempimento:

mysql_query("TRUNCATE TABLE `your_table`") or die(mysql_error()); 

Voglio dire, reimposta anche auto_increment (e cancella tutti i contenuti; Sì, la tabella rimarrà).

Problemi correlati