我需要运行一个也可以作为更新程序的安装程序。 安装程序需要能够最终拥有mysql数据库的某个方案/结构,无论是否存在某些表,错过了几列,或者由于其结构是最新的而无需更改。
如何优雅地组合ALTER
和CREATE
?
我当时认为必须有“添加...如果...重复”
假设我有表A.在一个客户端中,表有一列-A1,另一个客户端具有相同的表,但列A1和列A2。
我希望我的sql命令使两个客户端的表A保持三列:A1,A2和A3。
同样,我的脚本是一个我转储到mysql的sql文件。
我该怎么办?谢谢: - )
答案 0 :(得分:20)
MySQL INFORMATION_SCHEMA
数据库救援:
-- First check if the table exists
IF EXISTS(SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'db_name'
AND table_name LIKE 'wild')
-- If exists, retreive columns information from that table
THEN
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
AND table_schema = 'db_name';
-- do some action, i.e. ALTER TABLE if some columns are missing
ALTER TABLE ...
-- Table does not exist, create a new table
ELSE
CREATE TABLE ....
END IF;
更多信息:
<强>更新强>
另一个可能更简单的选择是删除现有表并使用新架构重新创建它。为此,您需要:
所以,在SQL代码中:
CREATE TABLE old_table_copy LIKE old_table;
INSERT INTO old_table_copy
SELECT * FROM old_table;
DROP TABLE old_table;
CREATE TABLE new_table (...new values...);
INSERT INTO new_table ([... column names from old table ...])
SELECT [...column names from old table ...]
FROM old_table_copy;
DROP TABLE old_table_copy;
实际上最后一步,“删除临时表。”,你可以跳过一段时间。为了以防万一,您可能希望对旧表进行某种备份,“只是在案例中”。
更多信息:
答案 1 :(得分:1)
如果您使用的是编码语言,请执行以下操作:
SHOW TABLES LIKE 'myTable'
如果返回值调用,则alter else调用create
答案 2 :(得分:0)
虽然这个话题已经有几年了,但我一直在寻找类似问题的解决方案。关于@GregD 的回答,我找到了一个适合我的解决方案。 SQL 脚本创建表,但是,如果数据库中已有表,则应应用更改。在这个版本中,它只有在有额外的列时才有效。修改后的(剩余)列不起作用。
-- We create a procedure that is dropped if it exists already.
DROP PROCEDURE IF EXISTS changeFunction;
-- We have to change the delimiter for the procedure.
DELIMITER $$
CREATE PROCEDURE changeFunction()
BEGIN
-- Check if table already exists
IF EXISTS(SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'your_database_name'
AND table_name LIKE 'your_table_name')
-- It exists, so create a new table and copy the data.
THEN
-- Copy the data into a copy of the table.
CREATE TABLE `your_table_name_copy` LIKE `your_table_name`;
INSERT INTO `your_table_name_copy` SELECT * FROM `your_table_name`;
-- Remove old table
DROP TABLE `your_table_name`;
-- Create the new table
CREATE TABLE IF NOT EXISTS `your_table_name` (
-- Your columns
);
-- Copy values, it determines the old column names by itself
SET @v1 := (SELECT GROUP_CONCAT(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_database_name' AND TABLE_NAME = 'your_table_name_copy');
-- Since the columns are detected automatically, we have to execute the
-- statement as prepared statement.
SET @q1 := CONCAT('INSERT INTO `your_table_name` (', @v1, ') ',
'SELECT ', @v1, ' FROM `your_table_name_copy`');
PREPARE stmt FROM @q1;
EXECUTE stmt;
-- Remove copy
DROP TABLE `your_table_name_copy`;
ELSE
-- It does not exist, simply create it
CREATE TABLE IF NOT EXISTS `your_table_name` (
-- Your columns
);
END IF;
END $$
-- Reset the delimiter
DELIMITER ;
-- Call the function
CALL changeFunction();