Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 列数不断变化的动态create语句的存储过程_Mysql_Stored Procedures_Create Table_Cursors - Fatal编程技术网

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

Mysql 列数不断变化的动态create语句的存储过程,mysql,stored-procedures,create-table,cursors,Mysql,Stored Procedures,Create Table,Cursors,我需要创建一个存储过程来创建一个动态的“create语句”,它将在每次运行时生成一个新的create语句。 表A有一列,该列有create语句中需要的列名列表。 例如: Table_A: columns abcd hijk defg 我的create语句应该如下所示: Table_A: columns abcd hijk defg cre

我需要创建一个存储过程来创建一个动态的“create语句”,它将在每次运行时生成一个新的create语句。
表A有一列,该列有create语句中需要的列名列表。
例如:

     Table_A:  columns   
      abcd   
      hijk   
      defg    
我的create语句应该如下所示:

     Table_A:  columns   
      abcd   
      hijk   
      defg    
    create table table_B (
    abcd varchar(255),
    hijk  varchar(255),
    defg varchar(255)
    );
几天后,表a中的列数可以改变/增加/减少,如下所示:

     Table_A:  columns   
      abcd   
      hijk   
      defg    
  Table_A: columns         
        abcd
        pqrs
        defg
        ghij
我的create语句应该如下所示:

     Table_A:  columns   
      abcd   
      hijk   
      defg    
    create table table_B ( 
    abcd varchar(255),
    pqrs  varchar(255),
    defg varchar(255),
    ghij varchar (255)
    );
我需要编写一个包含游标的存储过程

     Table_A:  columns   
      abcd   
      hijk   
      defg    
我从以下内容开始:

     Table_A:  columns   
      abcd   
      hijk   
      defg    
    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()    

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

如果我的原始评论不清楚,创建这样的表几乎从来都不是一个好主意。

     Table_A:  columns   
      abcd   
      hijk   
      defg    
但如果你必须,这里有一些方法

     Table_A:  columns   
      abcd   
      hijk   
      defg    
尝试替换/重新排列此部件(从原始问题/问题开始):

     Table_A:  columns   
      abcd   
      hijk   
      defg    
像这样的:

     Table_A:  columns   
      abcd   
      hijk   
      defg    
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;
SET @SQL_TXT 
   = SELECT CONCAT('CREATE TABLE Table_B ('
                   , GROUP_CONCAT(CONCAT('`', col, '` VARCHAR(255)') SEPARATOR ',')
                   , ');' AS theQuery
     FROM Table_A
;
循环将构建字段列表,子字符串()将删除前导“,”,最后一个concat将字段列表包装为实际的CREATE

     Table_A:  columns   
      abcd   
      hijk   
      defg    

或者,您可以像这样构建查询:

     Table_A:  columns   
      abcd   
      hijk   
      defg    
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;
SET @SQL_TXT 
   = SELECT CONCAT('CREATE TABLE Table_B ('
                   , GROUP_CONCAT(CONCAT('`', col, '` VARCHAR(255)') SEPARATOR ',')
                   , ');' AS theQuery
     FROM Table_A
;


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

这似乎有点像开始在RDBMS中构建RDBMS,只需要更改一条语句。set@SQL_TXT=concat('CREATE TABLE_B(',col1,'varchar(255));您试图创建一个包含多个列的表,因此不应该每次迭代都执行create查询。循环应该是建立一个查询,而不是每次迭代都重新分配查询文本(也不是每次迭代都重复“CREATETABLE”)。是的,我知道我需要编辑CREATE语句,使其能够每次循环并添加列。不知道怎么做?您提到的第一个选项多次循环并给出多个create语句。但是第二个选项使用group_concat,效果非常好。非常感谢!“第一个选项”是指问题的剪切和粘贴,还是重新整理?重新整理。如果替换的代码被完全替换,第一个选项不应该这样做。它的循环构建了一个字段列表;直到循环之后,“create”才被添加到字符串中。我可以执行这个过程,但是当我试图调用它时,会出现一个错误,告诉我:您的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,以了解在第1行SQL中使用接近“NULL”的正确语法。
     Table_A:  columns   
      abcd   
      hijk   
      defg