我可以在不知道现有列名称的情况下重命名 MySQL 列吗?
Can I rename a MySQL Column without knowing the existing column name?
我正在编写一系列 MySQL 查询来处理 table 中的数据。我有一个 table 是由我无法控制的系统自动生成的。当我得到它时,table 有几列:
ID、姓名、日期、标题和包含十进制值的列。
每次外部系统自动生成table时,它都会用当前日期命名包含小数值的值。目前,该列名为“16_Jul_17”,因为那是系统 运行 的最后一天。
我需要一种可靠的方法来查询 table(并重命名列),而不需要知道十进制值列的当前名称。有没有办法执行以下选项之一:
- 在不知道列名的情况下重命名小数值列
- 我可以使用 information_schema 来获取名称,但是我该如何使用它来重命名该列
您可以使用 ALTER TABLE CHANGE COLUMN
语句重命名列,但您必须先知道列的名称。
您必须使用 DESCRIBE <tablename>
或查询 INFORMATION_SCHEMA.COLUMNS
来获取 table.
中列的名称和数据类型
获得列名后,您可以为该列的 ALTER TABLE
语句格式化字符串。您应该使用应用程序代码执行此操作。
如果知道第N个列被定义的位置,可以使用查询来恢复第N个列名:
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TBL_NAME'
AND ORDINAL_POSITION = POSITION_YOUR_COLUMN
之后,您可以专门手动更改此列(通过 ALTER TABLE)或通过脚本自动更改(在 shell、python、...中生成 ALTER)
我找到了适合我的解决方法。我不知道它一般有多适用,但对于我的应用程序来说,它就像一个魅力。
由于我从外部来源知道 table 中列的顺序,因此我简单地使用 UNION ALL,如下所示:
Select 'Id', 'Name', 'Date', 'Title', 0.00 AS 'Value' LIMIT 0
UNION ALL
Select * from original_table
MySQL 使用值作为列名,除非明确别名。
请注意,LIMIT 0
是必需的,这样您就没有虚拟行。
我使用存储过程:
create procedure renamecolumn(in theTable varchar(128), in oldColumn varchar(128), in newColumn varchar(128)) begin
set @oldType := (select
concat(COLUMN_TYPE,
if(IS_NULLABLE="NO"," not null",""),
if(COLUMN_DEFAULT is not null,concat(" default ",if(DATA_TYPE!="int","'",""),COLUMN_DEFAULT,if(DATA_TYPE!="int","'","")),""),
if(COLUMN_KEY="PRI"," primary key","")," ",EXTRA) from information_schema.columns
where table_name = theTable and column_name = oldColumn and table_schema = database());
set @exist := (select count(*) from information_schema.columns
where table_name = theTable and column_name = newColumn and table_schema = database());
set @alterstmt := (select concat("alter table " ,theTable, " change column ", oldcolumn, " ", newColumn, " ", @oldType));
set @warningstmt := (select concat("a column with the name '" ,newColumn, "' already exists in ", theTable));
set @sqlstmt := if( @exist > 0, 'select @warningstmt as warning', @alterstmt);
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
end;
我正在编写一系列 MySQL 查询来处理 table 中的数据。我有一个 table 是由我无法控制的系统自动生成的。当我得到它时,table 有几列:
ID、姓名、日期、标题和包含十进制值的列。
每次外部系统自动生成table时,它都会用当前日期命名包含小数值的值。目前,该列名为“16_Jul_17”,因为那是系统 运行 的最后一天。
我需要一种可靠的方法来查询 table(并重命名列),而不需要知道十进制值列的当前名称。有没有办法执行以下选项之一:
- 在不知道列名的情况下重命名小数值列
- 我可以使用 information_schema 来获取名称,但是我该如何使用它来重命名该列
您可以使用 ALTER TABLE CHANGE COLUMN
语句重命名列,但您必须先知道列的名称。
您必须使用 DESCRIBE <tablename>
或查询 INFORMATION_SCHEMA.COLUMNS
来获取 table.
获得列名后,您可以为该列的 ALTER TABLE
语句格式化字符串。您应该使用应用程序代码执行此操作。
如果知道第N个列被定义的位置,可以使用查询来恢复第N个列名:
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TBL_NAME'
AND ORDINAL_POSITION = POSITION_YOUR_COLUMN
之后,您可以专门手动更改此列(通过 ALTER TABLE)或通过脚本自动更改(在 shell、python、...中生成 ALTER)
我找到了适合我的解决方法。我不知道它一般有多适用,但对于我的应用程序来说,它就像一个魅力。
由于我从外部来源知道 table 中列的顺序,因此我简单地使用 UNION ALL,如下所示:
Select 'Id', 'Name', 'Date', 'Title', 0.00 AS 'Value' LIMIT 0
UNION ALL
Select * from original_table
MySQL 使用值作为列名,除非明确别名。
请注意,LIMIT 0
是必需的,这样您就没有虚拟行。
我使用存储过程:
create procedure renamecolumn(in theTable varchar(128), in oldColumn varchar(128), in newColumn varchar(128)) begin
set @oldType := (select
concat(COLUMN_TYPE,
if(IS_NULLABLE="NO"," not null",""),
if(COLUMN_DEFAULT is not null,concat(" default ",if(DATA_TYPE!="int","'",""),COLUMN_DEFAULT,if(DATA_TYPE!="int","'","")),""),
if(COLUMN_KEY="PRI"," primary key","")," ",EXTRA) from information_schema.columns
where table_name = theTable and column_name = oldColumn and table_schema = database());
set @exist := (select count(*) from information_schema.columns
where table_name = theTable and column_name = newColumn and table_schema = database());
set @alterstmt := (select concat("alter table " ,theTable, " change column ", oldcolumn, " ", newColumn, " ", @oldType));
set @warningstmt := (select concat("a column with the name '" ,newColumn, "' already exists in ", theTable));
set @sqlstmt := if( @exist > 0, 'select @warningstmt as warning', @alterstmt);
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
end;