2010-03-09 8 views
25

Wiem, że to nie zadziała, wypróbowałem to w różnych formach i wszystko zawiodło. Jaki jest najprostszy sposób, aby osiągnąć następujący wynik?Jak zresetować AutoIncrement MySQL za pomocą wartości MAX z innej tabeli?

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

Jest to idealne rozwiązanie do projektów automatyzacji. Dziękuję Ci!

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? 

Odpowiedz

28

Użyj 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

Brzmi jak całkiem porządna odpowiedź na moje pytanie! Dziękuję Ci! – ThinkCode

+9

'PREPARE stmt FROM 'ALTER TABLE XYZ AUTO_INCREMENT =?'' generuje błąd dla mnie :( – bor

+0

@ T30 jaki jest twój błąd? – Beetle

1

Osobiście bym prawdopodobnie użyć skrypt lub niewiele C#/C++ aplikacji lub skryptu PHP/Ruby/Perl, aby zrobić to w 2 zapytaniami:

  • Grab wartość chcesz SELECT MAX(ID) FROM ABC;
  • Alter tabeli przy użyciu wartości ALTER TABLE XYZ AUTO_INCREMENT = <insert value retrieved from first query here>

Oczywiście uważając, że nowe auto przyrost nie będzie powodować żadnych kluczowych starć z istniejących danych w tabeli XYZ.

+0

Myślałem, że można to łatwo zrobić, używając tylko kwerend MySQL. Wygląda na to, że mam pecha. Każde inne rozwiązanie wykorzystujące tylko MySQL - używając zmiennych w MySQL? Chcę wykonać kilka zapytań w jednym pliku .sql zamiast skryptów powłoki i skryptów Perl/Python. Dzięki za odpowiedź. – ThinkCode

2

Ok chłopaki. Wymyśliłem nie tak intuicyjne rozwiązanie. Najlepsze jest to, że działa!

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

Skąd pochodzi ContactID? – T30

0

Jeśli naprawdę chcesz to zrobić w MySQL sam, można po prostu zrzucić dynamicznie zbudowany polecenia alter do pliku na dysku, a następnie uruchom go.

tak:

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

Dzięki za odpowiedź. To interesujące rozwiązanie! Może to być dodatkowa praca dla mojej sytuacji. – ThinkCode

5

Tworzę zautomatyzowany skrypt transformacji bazy danych do nowej wersji mojej aplikacji.

W jednej tabeli musiałem zmienić podstawowe pole automatycznego zwiększania na inne pole. Ponieważ ta strona wymyślił pierwsze wiele razy, podczas gdy ja googled rozwiązanie dla niego, oto rozwiązanie, które ostatecznie pracował dla mnie:

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

to faktycznie działa w mys ql 5.5 – shigeta

7

Kto mające problem z PRZYGOTOWAĆ stmt z "alter table XYZ AUTO_INCREMENT =? można użyć

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

Miałem duże nadzieje na ten, ale dostałem ten błąd: # 1064 - Masz błąd w składni SQL; sprawdź instrukcję, która odpowiada twojej wersji serwera MariaDB dla właściwej składni do użycia w pobliżu 'BEGIN SELECT @max: = MAX (id) + 1 FROM test' w linii 2 – kloddant

3

Resetuj automatyczne identyfikatory inkrementacji.

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

aktualizacja wszystkie kolumny automatycznego przyrostu bazy danych do najmniejszej możliwej wartości w oparciu o bieżące wartości w bazach danych. Musieliśmy to zrobić po wyczyszczeniu bazy danych.

Użyj przygotowaną instrukcję w procedura składowana:

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

następujące the mysql docs ten pracował dla mnie w 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

Jestem tylko amatorem, ale mam :-) Wskazówka Jeśli wypełnia całą tabelę z nowymi danymi, można po prostu użyć przed napełnieniem:

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

To znaczy, to również resetuje auto_increment (i usuwa całą zawartość, tak, tabela pozostanie).

Powiązane problemy