列数不断变化的动态create语句的存储过程

ldxq2e6h  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(329)

我需要创建一个存储过程来创建一个动态的“create statement”,它每次运行时都会生成一个新的create语句。
我有一个表\u a,它有一列,并且该列有create语句中需要的列名列表。
例子:

Table_A:  columns   
      abcd   
      hijk   
      defg

我的create语句应该如下所示:

create table table_B (
    abcd varchar(255),
    hijk  varchar(255),
    defg varchar(255)
    );

几天后,表a中的列数可以改变/增加/减少,如:

Table_A: columns         
        abcd
        pqrs
        defg
        ghij

我的create语句应该如下所示:

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()

当我在一个表中只有一行(在create table中只有一列)时,这种方法就可以很好地工作。当我有多个列时,我该怎么做呢。

fcipmucu

fcipmucu1#

如果从我最初的评论中不清楚,那么创建这样的表几乎从来都不是一个好主意。
但是如果你必须的话,这里有一些方法。。。。
尝试替换/重新排列此部分(从原始问题/问题开始):

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;

像这样:

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 Package 字段列表。
或者您可以这样构建查询:

SET @SQL_TXT 
   = SELECT CONCAT('CREATE TABLE Table_B ('
                   , GROUP_CONCAT(CONCAT('`', col, '` VARCHAR(255)') SEPARATOR ',')
                   , ');' AS theQuery
     FROM Table_A
;

也不是在这两种情况下,我用`字符分隔字段名;像“123”这样的字段名不能在没有分隔符的情况下使用。

相关问题