所以我知道为了在select语句中替换游标,我们需要在prepare语句之前定义它。我可以在那里替换变量,但我对游标有相同的问题。
例如,下面的语句应该正确地替换表的变量值,并且应该创建一个表作为trial_data。
SET @user := 'trial';
SET @group := 'data';
SET @table := CONCAT(@user, '_', @group);
SET @stat = CONCAT('CREATE TABLE ',@table,' as SELECT @user, @group;');
PREPARE stmt from @stat;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
但是,当我尝试在带有游标的存储过程中应用相同的逻辑时,我遇到如下错误 -
01:13:52 call cursor_ROWPERROW() Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1 0.000 sec
在这种情况下,我试图通过替换变量和游标的值来动态创建表。在这里,我试图根据我从信息模式中识别的另一个表中的相同列动态创建PD_yyyyy_xxxxx表。
DROP PROCEDURE IF EXISTS cursor_ROWPERROW;
DELIMITER $$
CREATE PROCEDURE cursor_ROWPERROW()
BEGIN
DECLARE cursor_COL VARCHAR(50);
DECLARE cursor_TAB VARCHAR(50);
DECLARE tab VARCHAR(100);
DECLARE col1 VARCHAR(50);
DECLARE col2 VARCHAR(50);
DECLARE done INT DEFAULT 0;
DECLARE cursor_i CURSOR FOR SELECT COLUMN_NAME, TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='xxxxx' AND TABLE_NAME='yyyyy' AND COLUMN_NAME = 'zzzzz';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cursor_i;
read_loop: LOOP
FETCH cursor_i INTO cursor_COL, cursor_TAB;
SET tab := CONCAT('PD', '_', @cursor_TAB, '_' , @cursor_COL);
SET col1 := CONCAT(@cursor_COL);
SET col2 := CONCAT(@cursor_COL, '_', 'value');
IF done THEN
LEAVE read_loop;
END IF;
SET @dyn_sql := CONCAT('CREATE TABLE ',@tab,' AS SELECT Codevalue as ',@col1,', valueLabel as ',@col2,' from valuesets14 where varName = cursor_COL and TableName = cursor_TAB;');
PREPARE stmt_dyn_view FROM @dyn_sql;
EXECUTE stmt_dyn_view;
DEALLOCATE PREPARE stmt_dyn_view;
END LOOP;
CLOSE cursor_i;
END;
$$
DELIMITER ;
虽然,我用下面的select语句替换整个SET @dyn_sql块,它运行正常,并为我提供了我想为其创建多个表的确切数据集。请注意,我引用的表中没有任何值是NULL,因此我似乎缺少使用游标替换的内容。
SELECT Codevalue as ',@col1,', valueLabel as ',@col2,' from valuesets14 where varName = cursor_COL and TableName = cursor_TAB;
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:1)
问题是你混淆了各种引用变量的方法。当你宣布它们时,应该省略@符号......
read_loop: LOOP
FETCH cursor_i INTO cursor_COL, cursor_TAB;
SET tab := CONCAT('PD', '_', cursor_TAB, '_' , cursor_COL);
SET col1 := CONCAT(cursor_COL);
SET col2 := CONCAT(cursor_COL, '_', 'value');
IF done THEN
LEAVE read_loop;
END IF;
SET @dyn_sql := CONCAT('CREATE TABLE ',tab,' AS SELECT Codevalue as ',col1,', valueLabel as ',col2,' from valuesets14 where varName = cursor_COL and TableName = cursor_TAB;');
PREPARE stmt_dyn_view FROM @dyn_sql;
EXECUTE stmt_dyn_view;
DEALLOCATE PREPARE stmt_dyn_view;
END LOOP;
答案 1 :(得分:0)
感谢Nigel的想法,然而,我仍然遇到了另一个问题,即它抱怨了光标变量替换
call cursor_ROWPERROW(): Error Code: 1054. Unknown column 'zzzzz' in 'where clause'
所以基本上,它无法替换游标值,所以我按照你提到的相同方法并为文本添加引号,因此使用select查询来查看它试图生成的查询我带来了下面的SQL解决了我的问题。
DROP PROCEDURE IF EXISTS cursor_ROWPERROW;
DELIMITER $$
CREATE PROCEDURE cursor_ROWPERROW()
BEGIN
DECLARE cursor_COL VARCHAR(50);
DECLARE cursor_TAB VARCHAR(50);
DECLARE tab VARCHAR(100);
DECLARE col1 VARCHAR(50);
DECLARE col2 VARCHAR(50);
DECLARE done INT DEFAULT 0;
DECLARE cursor_i CURSOR FOR SELECT COLUMN_NAME, TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='xxxxx' AND TABLE_NAME='yyyyy' AND COLUMN_NAME = 'zzzzz';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cursor_i;
read_loop: LOOP
FETCH cursor_i INTO cursor_COL, cursor_TAB;
SET tab := CONCAT('PD', '_', cursor_TAB, '_' , cursor_COL);
SET col1 := CONCAT(cursor_COL);
SET col2 := CONCAT(cursor_COL, '_', 'value');
IF done THEN
LEAVE read_loop;
END IF;
SET @dyn_sql := CONCAT('CREATE TABLE ',tab,' AS SELECT Codevalue as ',col1,', valueLabel as ',col2,' from valuesets14 where varName = "',cursor_COL,'" and TableName = "',cursor_TAB,'";');
PREPARE stmt_dyn_view FROM @dyn_sql;
#SELECT @dyn_sql;
EXECUTE stmt_dyn_view;
DEALLOCATE PREPARE stmt_dyn_view;
END LOOP;
CLOSE cursor_i;
END;
$$
DELIMITER ;