2012-05-31 4 views
11

In meiner MySQL InnoDB Datenbank mit Fremdschlüsseln habe ich versehentlich einige meiner Primärschlüssel signiert anstatt unsigniert, wie ich es möchte.Wie ändere ich den MySQL-Primärschlüssel von signiert in unsigned?

Jetzt möchte ich es mit einer ALTER TABLE-Anweisung ändern, aber es funktioniert nicht:

ALTER TABLE `users` CHANGE `id` `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT 

MySQL Fehler:

Error on rename of './db_dev/#sql-478_3' to './db_dev/users' (errno: 150) 

Ich verstehe nicht, warum. Ich arbeite mit Fremdschlüssel und versuchte mit einer

Anweisung vor der Ausführung der ALTER TABLE von oben. Funktioniert auch nicht. Hinweis: Alle meine Tabellen sind noch leer. Es sind noch keine Daten drin.

Da die Datenbank viele Tabellen enthält, wäre es sehr viel Mühe, alle Fremdschlüssel zu löschen und sie manuell hinzuzufügen. (wenn das der Grund sein sollte).

Antwort

9

Dieses Feld in Fremdschlüssel verwendet wird (s). Um dieses Feld zu ändern in MySQL, sollten Sie diese Schritte durchführen:

  • Tropfen alle damit verbundenen Fremdschlüssel
  • ändern Feld
  • Recreate alle Fremdschlüssel gelöscht
+0

Danke. Das funktioniert, ist aber lästig. – Norwald2

+0

Ja, ist es. Sie können die Spaltenumbenennung mit Refactoring in [dbForge Studio für MySQL] versuchen (http://www.devart.com/dbforge/mysql/studio/); Es wird automatisch ausgeführt (im Datenbank-Explorer). – Devart

+0

Ich habe diesen Ansatz und Skript den gesamten Prozess, siehe Antwort https://stackoverflow.com/a/47169383/1241791 – Sam

1

Versuchen Sie, diese
ALTER TABLE 'users' MODIFY 'id' UNSIGNED NOT NULL AUTO_INCREMENT'

+0

funktioniert auch nicht. – Norwald2

5

Werfen Sie einen Dump der Datenbank mysql Befehl mysqldump und suchen und unsigned jede Stelle wo erforderlich. Stellen Sie dann den Speicherauszug in derselben Datenbank wieder her. Vor dem Wiederherstellen löschen Sie alle Tabellen und legen Sie sie ab.

+0

Viel einfacher als das Löschen von Fremdschlüsseln. (Wenn Sie dies tun können) – AntonioCS

+0

Nicht alle meine Fremdschlüssel neu erstellen musste ich viel Zeit gespart. –

0

MySQL Workbench können Sie dies tun. Sie müssen sicherstellen, dass Sie PRIMARY KEY und alle Spalten in jeder Tabelle ändern, auf die ein Fremdschlüssel verweist.

Ich fand es auf einer Reihe von Szenarien zu arbeiten, YMMV.

0

Ich übernahm ein Projekt, das ein identisches Problem einiger Primärschlüssel signiert hatte, und das zugehörige Fremdfeld wurde ebenfalls signiert.

Ich verwendete @Devart Ansatz, aber ich war in der Lage, den gesamten Prozess zu automatisieren. Ich konnte die information_schema abfragen, um zusätzliche SQL-Anweisungen zu generieren, die ich "ausschneiden und einfügen" und dann später ausführen konnte.

Generieren von SQL-Anweisungen alle Einschränkungen

SELECT concat('ALTER TABLE ', TABLE_NAME, ' DROP FOREIGN KEY ', CONSTRAINT_NAME, ';') 
FROM information_schema.key_column_usage 
WHERE CONSTRAINT_SCHEMA = 'YOUR_SCHEMA_NAME' 
AND referenced_table_name IS NOT NULL; 

Alter alle id Spalten zu löschen, die zu UNSIGNED

SELECT 
    CONCAT('ALTER TABLE `', TABLE_NAME, '` CHANGE COLUMN id id INT UNSIGNED NOT NULL AUTO_INCREMENT;') 
FROM `COLUMNS` 
WHERE 
    `COLUMN_KEY` = 'PRI' AND 
    `TABLE_SCHEMA` = 'YOUR_SCHEMA_NAME' AND 
    `COLUMN_TYPE` NOT LIKE '%unsigned%' AND 
    `COLUMN_TYPE` LIKE '%int%' AND 
    `COLUMN_NAME` = 'id'; 

Alter ausländische Felder zum id

Hinweis geändert werden müssen,
SELECT CONCAT('ALTER TABLE `', kcu.TABLE_NAME, '` CHANGE COLUMN ', kcu.COLUMN_NAME,' ', kcu.COLUMN_NAME, ' INT UNSIGNED ', IF(c.IS_NULLABLE = 'YES', 'NULL', 'NOT NULL'), ';') 
FROM `KEY_COLUMN_USAGE` kcu 
INNER JOIN `COLUMNS` c 
ON 
    kcu.TABLE_NAME = c.TABLE_NAME AND 
    kcu.COLUMN_NAME = c.COLUMN_NAME 
WHERE 
    `REFERENCED_COLUMN_NAME` = 'id' AND 
    `REFERENCED_TABLE_NAME` IN (
    SELECT 
     TABLE_NAME 
    FROM `COLUMNS` 
    WHERE 
     `COLUMN_KEY` = 'PRI' AND 
     `TABLE_SCHEMA` = 'YOUR_SCHEmA_NAME' AND 
     `COLUMN_TYPE` NOT LIKE '%unsigned%' AND 
     `COLUMN_TYPE` LIKE '%int%' AND 
     `COLUMN_NAME` = 'id' 
); 

(Hinweis in dieser Erklärung werden alle geändert versehentlich ohne Vorzeichen werden auch wenn sie schon nicht signiert sind, aber dies verursacht keine Probleme)

Reinsert alle erforderlichen Einschränkungen

SELECT CONCAT('ALTER TABLE ', rc.`TABLE_NAME` ,' ADD CONSTRAINT ', rc.`CONSTRAINT_NAME`, ' FOREIGN KEY (',kcu.`COLUMN_NAME`,') REFERENCES ', rc.`REFERENCED_TABLE_NAME` ,'(id) ON DELETE ', DELETE_RULE , ' ON UPDATE ' , UPDATE_RULE, ';') 
FROM `REFERENTIAL_CONSTRAINTS` rc 
INNER JOIN 
    `KEY_COLUMN_USAGE` kcu 
    ON rc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME 
WHERE kcu.CONSTRAINT_SCHEMA = 'api'  AND 
kcu.`REFERENCED_COLUMN_NAME` = 'id'; 

Achten Sie genau auf diese SQL-Anweisungen. Sie müssen möglicherweise für Ihr Schema geändert werden, z. B. wird davon ausgegangen, dass Ihre primäre ID "id" heißt.

Sie müssen auch alle 4 dieser Anweisungen ausführen, bevor Sie eine ihrer tatsächlichen Ausgaben ausführen.

Verwenden von MySQL 5.6