列数不断变化的动态创建语句的存储过程
Stored procedure for dynamic create statement where number of columns keep changing
我需要创建一个存储过程来创建一个动态 'create statement',它会在每次运行时生成一个新的创建语句。
我有 table_A 一列,该列包含创建语句中需要的列名列表。
示例:
Table_A: columns
abcd
hijk
defg
我的创建语句应该如下所示:
create table table_B (
abcd varchar(255),
hijk varchar(255),
defg varchar(255)
);
几天后 Table_A 中的列数可以 change/increase/decrease 像:
Table_A: columns
abcd
pqrs
defg
ghij
我的创建语句应该如下所示:
create table table_B (
abcd varchar(255),
pqrs varchar(255),
defg varchar(255),
ghij varchar (255)
);
我需要编写一个涉及游标的存储过程。
我从这样的事情开始:
Delimiter $$
DROP PROCEDURE IF EXISTS sp_test2 $$
CREATE PROCEDURE sp_test2()
BEGIN
DECLARE DONE INT DEFAULT 0;
DECLARE col1 varchar(255);
DECLARE curA CURSOR FOR select col AS column_name from Table_A;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET DONE = 1;
OPEN curA;
DROP TABLE IF EXISTS Table_B;
while done = 0 do
fetch next from CurA into col;
if done = 0 then
set @SQL_TXT = concat('CREATE TABLE Table_B (',col1,' varchar(255))');
-- select @SQL_TXT
PREPARE stmt_name FROM @SQL_TXT;
EXECUTE stmt_name;
DEALLOCATE PREPARE stmt_name;
end if;
end while;
close curA;
end
call sp_test2()
当我在 table 中只有一行(这只是创建 table 中的一列)时,这很好用。当我有多个列时,我该怎么做。
如果我最初的评论不清楚,创建这样的表几乎不是一个好主意。
但如果你必须这样做,这里有一些方法....
尝试replacing/rearranging这部分(来自原文question/problem):
DROP TABLE IF EXISTS Table_B;
while done = 0 do
fetch next from CurA into col;
if done = 0 then
set @SQL_TXT = concat('CREATE TABLE Table_B (',col1,' varchar(255))');
-- select @SQL_TXT
PREPARE stmt_name FROM @SQL_TXT;
EXECUTE stmt_name;
DEALLOCATE PREPARE stmt_name;
end if;
end while;
close curA;
with/like 像这样:
DROP TABLE IF EXISTS Table_B;
SET @SQL_TXT = '';
while done = 0 do
fetch next from CurA into col;
if done = 0 then
set @SQL_TXT = concat(@SQL_TXT, ', `', col1, '` varchar(255)');
end if;
end while;
close curA;
SET @SQL_TXT = CONCAT('CREATE TABLE Table_B (', SUBSTRING(@SQL_TXT, 2), ')');
PREPARE stmt_name FROM @SQL_TXT;
EXECUTE stmt_name;
DEALLOCATE PREPARE stmt_name;
循环构建您的字段列表,SUBSTRING() 删除前导“,”,最后的 concat 用实际的 CREATE 包装字段列表。
或者您可以像这样构建查询:
SET @SQL_TXT
= SELECT CONCAT('CREATE TABLE Table_B ('
, GROUP_CONCAT(CONCAT('`', col, '` VARCHAR(255)') SEPARATOR ',')
, ');' AS theQuery
FROM Table_A
;
也不是在这两种情况下,我都用`字符分隔字段名称;像“123”这样的字段名称不能不加分隔符使用。
我需要创建一个存储过程来创建一个动态 'create statement',它会在每次运行时生成一个新的创建语句。
我有 table_A 一列,该列包含创建语句中需要的列名列表。
示例:
Table_A: columns
abcd
hijk
defg
我的创建语句应该如下所示:
create table table_B (
abcd varchar(255),
hijk varchar(255),
defg varchar(255)
);
几天后 Table_A 中的列数可以 change/increase/decrease 像:
Table_A: columns
abcd
pqrs
defg
ghij
我的创建语句应该如下所示:
create table table_B (
abcd varchar(255),
pqrs varchar(255),
defg varchar(255),
ghij varchar (255)
);
我需要编写一个涉及游标的存储过程。
我从这样的事情开始:
Delimiter $$
DROP PROCEDURE IF EXISTS sp_test2 $$
CREATE PROCEDURE sp_test2()
BEGIN
DECLARE DONE INT DEFAULT 0;
DECLARE col1 varchar(255);
DECLARE curA CURSOR FOR select col AS column_name from Table_A;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET DONE = 1;
OPEN curA;
DROP TABLE IF EXISTS Table_B;
while done = 0 do
fetch next from CurA into col;
if done = 0 then
set @SQL_TXT = concat('CREATE TABLE Table_B (',col1,' varchar(255))');
-- select @SQL_TXT
PREPARE stmt_name FROM @SQL_TXT;
EXECUTE stmt_name;
DEALLOCATE PREPARE stmt_name;
end if;
end while;
close curA;
end
call sp_test2()
当我在 table 中只有一行(这只是创建 table 中的一列)时,这很好用。当我有多个列时,我该怎么做。
如果我最初的评论不清楚,创建这样的表几乎不是一个好主意。
但如果你必须这样做,这里有一些方法....
尝试replacing/rearranging这部分(来自原文question/problem):
DROP TABLE IF EXISTS Table_B;
while done = 0 do
fetch next from CurA into col;
if done = 0 then
set @SQL_TXT = concat('CREATE TABLE Table_B (',col1,' varchar(255))');
-- select @SQL_TXT
PREPARE stmt_name FROM @SQL_TXT;
EXECUTE stmt_name;
DEALLOCATE PREPARE stmt_name;
end if;
end while;
close curA;
with/like 像这样:
DROP TABLE IF EXISTS Table_B;
SET @SQL_TXT = '';
while done = 0 do
fetch next from CurA into col;
if done = 0 then
set @SQL_TXT = concat(@SQL_TXT, ', `', col1, '` varchar(255)');
end if;
end while;
close curA;
SET @SQL_TXT = CONCAT('CREATE TABLE Table_B (', SUBSTRING(@SQL_TXT, 2), ')');
PREPARE stmt_name FROM @SQL_TXT;
EXECUTE stmt_name;
DEALLOCATE PREPARE stmt_name;
循环构建您的字段列表,SUBSTRING() 删除前导“,”,最后的 concat 用实际的 CREATE 包装字段列表。
或者您可以像这样构建查询:
SET @SQL_TXT
= SELECT CONCAT('CREATE TABLE Table_B ('
, GROUP_CONCAT(CONCAT('`', col, '` VARCHAR(255)') SEPARATOR ',')
, ');' AS theQuery
FROM Table_A
;
也不是在这两种情况下,我都用`字符分隔字段名称;像“123”这样的字段名称不能不加分隔符使用。