MySQL临时表不清楚

时间:2014-01-07 00:55:05

标签: mysql sql stored-procedures temp-tables

背景 - 我有一个从一个大的平面文件创建的数据库。而不是创建一个包含106列的单个大表。我创建了一个“columns”表,它存储列名和保存该数据的表的id,以及106个其他表来存储每列的数据。由于并非所有记录都包含所有列中的数据,我认为这可能是一种更有效的加载数据的方法(可能是一个坏主意)。

这方面的困难是从这个结构重建单个记录。为此,我创建了以下过程:

DROP PROCEDURE IF EXISTS `col_val`;
delimiter $$

CREATE PROCEDURE `col_val`(IN id INT)
BEGIN
    DROP TEMPORARY TABLE IF EXISTS tmp_record;
    CREATE TEMPORARY TABLE tmp_record (id INT(11), val varchar(100)) ENGINE=MEMORY;
    SET @ctr = 1;
    SET @valsql = '';
    WHILE (@ctr < 107) DO
        SET @valsql = CONCAT('INSERT INTO tmp_record SELECT ',@ctr,', value FROM col',@ctr,' WHERE recordID = ',@id,';');
        PREPARE s1 FROM @valsql;
        EXECUTE s1;
        DEALLOCATE PREPARE s1;
        SET @ctr = @ctr+1;
        END WHILE;
END$$
DELIMITER ;

然后我使用以下SQL,其中存储过程参数是我想要的记录的id。

CALL col_val(10);
SELECT c.`name`, t.`val`
FROM `columns` c INNER JOIN tmp_record t ON c.ID = t.id

问题 - 我第一次运行它时效果很好。但是,即使参数已更改,每个后续运行也会返回完全相同的记录。即使存储过程应该丢弃并重新创建临时表,这仍然如何?

我可能会重新思考整个设计并回到单个表格,但这个问题说明了我想要了解的内容。

不确定是否重要但我在Windows 7上运行MySQL 5.6(64位)并通过MySQL Workbench v5.2.47 CE执行SQL。

谢谢,

1 个答案:

答案 0 :(得分:0)

在MySQL存储过程中,不要在局部变量(输入参数或本地声明的变量)前放置@符号。您使用的@id引用了user variable,它有点像您正在调用过程的会话的全局变量。

换句话说,@id是与id不同的变量。

这就是你所遇到的直接问题的解释。但是,我不会像你那样设计表格。

  

由于并非所有记录都包含所有列中的数据,我认为这可能是一种更有效的加载数据的方法

我建议使用传统的单表,并使用NULL表示缺少的数据。