2010-03-09 3 views
25

Ich weiß, das wird nicht funktionieren, versuchte es in verschiedenen Formen und alle Male fehlgeschlagen. Was ist der einfachste Weg, um das folgende Ergebnis zu erzielen?Zurücksetzen eines MySQL AutoIncrement mit einem MAX-Wert aus einer anderen Tabelle?

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

Dies ist ideal für Automatisierungsprojekte. Vielen Dank!

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? 

Antwort

28

Verwenden Sie ein 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

Klingt wie eine ziemlich solide Antwort für meine Frage! Vielen Dank! – ThinkCode

+9

'PREPARE stmt FROM 'ALTER TABELLE XYZ AUTO_INCREMENT =?'' Fehler für mich erzeugen :( – bor

+0

@ T30 was ist Ihr Fehler? – Beetle

1

Persönlich würde ich wahrscheinlich entweder ein Shell-Skript oder ein wenig C#/C++ Anwendung oder PHP/Ruby-/ Perl-Skript, dies zu tun in 2 Abfragen verwenden:

  • Nimm den Wert, den Sie SELECT MAX(ID) FROM ABC; wollen
  • Ändern Sie die Tabelle den Wert mit ALTER TABLE XYZ AUTO_INCREMENT = <insert value retrieved from first query here>

Offensichtlich darauf achten, dass die neue Autoinkrement keine Schlüssel Kollisionen mit vorhandenen Daten verursachen in der XYZ Tabelle.

+0

Ich dachte, es kann einfach mit nur MySQL-Abfragen durchgeführt werden. Sieht so aus, als hätte ich kein Glück. Jede andere Lösung, die nur MySQL verwendet - mit Variablen in MySQL? Ich möchte eine Reihe von Abfragen in einer .sql-Datei statt Shell-Skripten und Perl/Python-Skripten ausführen. Danke für die Antwort. – ThinkCode

2

Ok Jungs. Ich habe eine nicht so intuitive Lösung gefunden. Das Beste ist, dass es funktioniert!

+0

Woher kommt ContactID? – T30

0

Wenn Sie dies wirklich nur in MySQL tun möchten, können Sie den dynamisch erstellten alter-Befehl einfach in eine Datei auf der Festplatte kopieren und dann ausführen.

Wie so:

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

Danke für die Antwort. Das ist eine interessante Lösung! Kann eine kleine zusätzliche Arbeit für meine Situation sein. – ThinkCode

5

Ich bin für eine neue Version meiner Anwendung eine automatisierte Datenbank Transformation Skript erstellen.

In einer Tabelle musste ich das primäre Auto-Inkrement-Feld in ein anderes Feld ändern. Da diese Seite erst viele Male kam, während ich eine Lösung für sie gegoogelt, hier ist eine Lösung, die schließlich für mich gearbeitet:

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

das funktioniert tatsächlich in mys ql 5.5 – shigeta

7

Wer Problem mit PREPARE Anw FROM wird mit ‚ALTER TABLE XYZ AUTO_INCREMENT =?‘ kann verwendet werden

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

Ich hatte große Hoffnungen für diese, aber ich bekomme diesen Fehler: # 1064 - Sie haben einen Fehler in Ihrer SQL-Syntax; Überprüfen Sie das Handbuch, das Ihrer MariaDB-Serverversion entspricht, damit die richtige Syntax in der Nähe von 'BEGIN SELECT @max: = MAX (id) + 1 FROM test' in Zeile 2 verwendet wird – kloddant

3

Auto-Inkrement-IDs zurücksetzen.

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

Update alle Autoinkrement-Spalten in einer Datenbank auf den kleinstmöglichen Wert, basierend auf aktuellen Werten in den Datenbanken. Wir mussten dies tun, nachdem wir eine Datenbank gelöscht hatten.

eine vorbereitete Anweisung innerhalb einer gespeicherten Prozedur verwenden:

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

folgenden the mysql docs, das war für mich 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

Ich bin nur ein Amateur, aber ich habe einen Tipp :-) Wenn Sie Ihre gesamte Tabelle mit neuen Daten füllen, die Sie gerade vor dem Befüllen verwenden können:

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

Ich meine, es setzt auch auto_increment zurück (und löscht alle Inhalte; Ja, Tabelle bleibt).

Verwandte Themen