过程中的动态SQL查询

时间:2014-01-10 01:25:33

标签: mysql stored-procedures

我想创建一个动态表,但我创建表的构建字符串是NULL - 为什么?
目标是从现有表中获取列值,并使用以这些值命名的列创建新表。

DELIMITER $$
DROP PROCEDURE IF EXISTS fanart_test.get_incomplete_artwork $$
CREATE PROCEDURE fanart_test.get_incomplete_artwork()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE type_id INT;
DECLARE type_name INT;
DECLARE build_string VARCHAR(20000);

DECLARE cursor1 CURSOR FOR 
    SELECT type_id,type_name FROM fanart_types WHERE type_section = 3;


DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;

OPEN cursor1;

get_results: LOOP
    FETCH cursor1 INTO type_id, type_name;
    IF finished = 1 
    THEN LEAVE get_results;
    END IF;

    IF build_string = ""
    THEN SET build_string = CONCAT('CREATE TABLE `tmp_incomplete_artwork`(`', type_name, '` TEXT');
    ELSE SET build_string = CONCAT(build_string,',', type_name);
    END IF;

    SET build_string = CONCAT(build_string,')');

END LOOP get_results;
CLOSE cursor1;

SET @s = build_string;
PREPARE build FROM @s;
EXECUTE build;
DEALLOCATE PREPARE build;

END $$

1 个答案:

答案 0 :(得分:1)

DECLARE build_string VARCHAR(20000);

build_string最初未设置为任何内容,因此它可能为NULL。

IF build_string = ""

这永远不会返回true,因为NULL = ""不是真的。

ELSE SET build_string = CONCAT(build_string,',', type_name);

使用NULL连接任何字符串都会返回NULL。


重新评论:

您已将变量type_idtype_name命名为与表格中的列名称相同的变量。这会产生歧义,事实证明MySQL更喜欢将标识符解释为局部变量,而不是列名。

所以这个:

SELECT type_id,type_name FROM fanart_types WHERE type_section = 3;

将返回type_id和type_name的当前值,该值未初始化,即NULL。因此,为表的所有行返回一对NULL。

只需将变量重命名为与表的列名不同,或者对列进行限定,使它们显然是列而不是变量:

SELECT f.type_id, f.type_name FROM fanart_types f WHERE f.type_section = 3;

此外,您可能希望将type_name声明为TEXT而不是INT