解决了这个问题。我最终完成了一个 5 步程序:
- 保存给定主键的每个外键约束
- 移除上述限制
- 删除主键
- 应用主键和自动增量
- 再次应用每个外键
CREATE OR REPLACE PROCEDURE alter_primary_key(P_SCHEMA VARCHAR(64), P_TABLE VARCHAR(64), P_COLUMN VARCHAR(64)) MODIFIES SQL DATA
BEGIN
DECLARE V_CONSTRAINT_SCHEMA VARCHAR(64);
DECLARE V_TABLE_NAME VARCHAR(64);
DECLARE V_CONSTRAINT_NAME VARCHAR(64);
DECLARE V_COLUMN_NAME VARCHAR(64);
DECLARE V_REFERENCED_TABLE_SCHEMA VARCHAR(64);
DECLARE V_REFERENCED_TABLE_NAME VARCHAR(64);
DECLARE V_REFERENCED_COLUMN_NAME VARCHAR(64);
DECLARE C CURSOR FOR SELECT CONSTRAINT_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM foreign_keys;
CREATE OR REPLACE TEMPORARY TABLE magi.foreign_keys (CONSTRAINT_SCHEMA VARCHAR(64), TABLE_NAME VARCHAR(64), CONSTRAINT_NAME VARCHAR(64), COLUMN_NAME VARCHAR(64), REFERENCED_TABLE_SCHEMA VARCHAR(64), REFERENCED_TABLE_NAME VARCHAR(64), REFERENCED_COLUMN_NAME VARCHAR(64));
INSERT INTO magi.foreign_keys (CONSTRAINT_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME)
SELECT CONSTRAINT_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_SCHEMA = P_SCHEMA AND REFERENCED_TABLE_NAME = P_TABLE AND REFERENCED_COLUMN_NAME = P_COLUMN;
OPEN C;
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
read_loop: LOOP
FETCH C INTO V_CONSTRAINT_SCHEMA, V_TABLE_NAME, V_CONSTRAINT_NAME, V_COLUMN_NAME, V_REFERENCED_TABLE_SCHEMA, V_REFERENCED_TABLE_NAME, V_REFERENCED_COLUMN_NAME;
IF done THEN
LEAVE read_loop;
END IF;
SET @STMT = CONCAT('ALTER TABLE ', V_CONSTRAINT_SCHEMA, '.', V_TABLE_NAME, ' DROP FOREIGN KEY ', V_CONSTRAINT_NAME);
PREPARE STMT FROM @STMT;
EXECUTE STMT;
END LOOP;
END;
CLOSE C;
SET @STMT = CONCAT('ALTER TABLE ' , P_SCHEMA , '.' , P_TABLE , ' DROP PRIMARY KEY');
PREPARE STMT FROM @STMT;
EXECUTE STMT;
# SET @STMT = CONCAT('ALTER TABLE ' , P_SCHEMA , '.' , P_TABLE , ' MODIFY COLUMN ' , P_COLUMN , ' bigint AUTO_INCREMENT NOT NULL PRIMARY KEY');
SET @STMT = CONCAT('ALTER TABLE ' , P_SCHEMA , '.' , P_TABLE , ' MODIFY COLUMN ', P_COLUMN ,' bigint AUTO_INCREMENT PRIMARY KEY');
PREPARE STMT FROM @STMT;
EXECUTE STMT;
OPEN C;
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
read_loop2: LOOP
FETCH C INTO V_CONSTRAINT_SCHEMA, V_TABLE_NAME, V_CONSTRAINT_NAME, V_COLUMN_NAME, V_REFERENCED_TABLE_SCHEMA, V_REFERENCED_TABLE_NAME, V_REFERENCED_COLUMN_NAME;
IF done THEN
LEAVE read_loop2;
END IF;
SET @STMT = CONCAT('ALTER TABLE ',V_CONSTRAINT_SCHEMA,'.',V_TABLE_NAME,' ADD CONSTRAINT ',V_CONSTRAINT_NAME,' FOREIGN KEY (',V_COLUMN_NAME,') REFERENCES ' , V_REFERENCED_TABLE_SCHEMA , '.' , V_REFERENCED_TABLE_NAME,' (',V_REFERENCED_COLUMN_NAME,')');
PREPARE STMT FROM @STMT;
EXECUTE STMT;
END LOOP;
END;
CLOSE C;
END
CALL alter_primary_key('mydatabase', 'mytable', 'id');