【问题标题】:error delcare cursor mysql stored procedure错误delcare游标mysql存储过程
【发布时间】:2017-01-14 02:36:38
【问题描述】:

我有下一个存储过程,我之前用光标在 mysql 中创建了其他过程但是我这个,mysql 给我一个错误:该过程是下一个:

DROP PROCEDURE IF EXISTS systm;

delimiter //

CREATE PROCEDURE systm()
BEGIN
    DECLARE bdone INT;
    DECLARE var1 VARCHAR(250);
    DECLARE var2 VARCHAR(250);
    DECLARE puntero VARCHAR(5);


    SET @query = CONCAT('CREATE TABLE IF NOT EXISTS `wg_init` (
                         `id` int(10) NOT NULL AUTO_INCREMENT,
                         `nombre` varchar(200) NOT NULL,
                         `valor` varchar(500) NOT NULL,
                          PRIMARY KEY (`id`)
                        ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;');

    PREPARE stmt FROM @query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    DECLARE curs CURSOR FOR SELECT `nombre` FROM `wg_datos`;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;

    OPEN curs;

    SET bdone = 0;
    REPEAT
      FETCH curs INTO puntero;

      SET @slt = CONCAT( 'SELECT nombre,valor INTO var1,var2 FROM wg_datos WHERE id =',puntero,'and nombre NOT LIKE "%descripcion%" ' ); 
      PREPARE stmt FROM @slt;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;

      SET @query = CONCAT('INSERT INTO wg_init(nombre,valor) VALUES (',var1,',',var2,' ) ');

      PREPARE stmt FROM @query;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;

    UNTIL bdone END REPEAT;
    CLOSE curs;
END
//

delimiter ;

CALL systm();

程序很简单,接下来要做的就是:

首先,创建一个表,然后,另一个查询通过游标获取选择获取的id,每行,它从获取游标获得的id中选择(nombre,valor)并在新的执行插入表与之前获得的值。这很容易,但 mysql 会向我发送这样的错误:

#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 'DECLARE curs CURSOR FOR SELECT `nombre` FROM `wg_datos`;

DECLARE CONT' at line 15 

我已尝试执行查询:

SELECT nombre FROM wg_datos

并且工作正常。

谁能帮帮我?

【问题讨论】:

  • MySQL 对存储程序中语句的顺序非常严格... "DECLARE 只允许在 BEGIN ... END 复合语句中,并且必须在其开始处,在任何其他语句之前。声明必须遵循一定的顺序。游标声明必须出现在处理程序声明之前。变量和条件声明必须出现在游标或处理程序声明之前。 dev.mysql.com/doc/refman/5.7/en/declare.html "变量声明必须出现在游标或处理程序声明之前。" dev.mysql.com/doc/refman/5.7/en/declare-local-variable.html
  • 我明白了,但现在如果我执行它会告诉我这个错误:未声明的变量 var1,并且在开始时声明了 var1。我在做什么??
  • 检查包含INTO var1,var2 的动态SELECT 语句...该语句的上下文不包括过程变量。这些过程变量不在动态 SELECT 的范围内。我完全糊涂了。首先,为什么你需要一个游标循环(而不是一口气处理整个集合),如果你绝对需要在一个缓慢的游标循环中处理这个 RBAR(逐行),为什么你需要一个动态语句,为什么不在已经检索“nombre”的游标中返回“valor”。
  • 我需要在wg_init 中插入wg_datos 的数据,除了包含 %descripcion% 的值,确定是否可以在一个查询中执行此操作,但我会尝试这种方法来练习。我如何才能将 var1,var2 包含在该语句的上下文中?你能给我举个例子吗?谢谢
  • 当你不应该使用光标时,为什么还要练习使用光标?如果您不是 DBA,就没有理由需要编写游标。

标签: mysql sql cursor procedure


【解决方案1】:

首先,我不明白为什么你需要一个游标循环来处理集合 RBAR(逐行痛苦),为什么你不一口气完成。

再一次,不清楚为什么要从wg_datos 获取nombre,然后在针对id 列的相等谓词中使用该值。

nombre 的值被提取到 VARCHAR(5) 变量中。我们没有看到id 的数据类型在wg_datos 中。

不清楚这个存储过程应该实现什么,我认为这些问题比 DECLARE 语句顺序的语法问题要深得多。

如果我们进行游标循环,并将nombre 的值提取到VARCHAR(5) 中,然后将该值用于与id 列的比较... SELECT ... INTO .. . 如果返回多于一行,将会抛出错误...

这一切看起来都很奇怪。看起来该过程将处理一组类似于这样的查询返回的集合:

SELECT v.nombre
     , v.valor
  FROM wg_datos i
  JOIN wg_datos v
    ON v.id = SUBSTRING(i.nombre,1,5)
   AND v.nombre NOT LIKE '%descripcion%'

当然,与过程的不同之处在于,如果SELECT ... INTO ... 不返回一行,则过程仍将处理INSERT 语句。

很奇怪。

除了奇怪的代码,我不知道这个过程实际上应该完成什么。


如果意图只是将行从wg_datos 复制到wg_init,不包括名称中包含字符串“描述”的行,并将新的 auto_increment id 值分配给 wg_init 中的行...

 CREATE PROCEDURE systm()
 BEGIN
    SET @query = CONCAT('CREATE TABLE IF NOT EXISTS `wg_init` (
                     `id` int(10) NOT NULL AUTO_INCREMENT,
                     `nombre` varchar(200) NOT NULL,
                     `valor` varchar(500) NOT NULL,
                      PRIMARY KEY (`id`)
                    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;');

    PREPARE stmt FROM @query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    INSERT INTO wg_init(nombre,valor)
    SELECT d.nombre
         , d.valor
      FROM wg_datos d
     WHERE d.nombre NOT LIKE '%descripcion%'
    ;

 END$$

 DELIMITER ;

【讨论】:

    猜你喜欢
    • 2013-09-28
    • 2020-12-27
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    相关资源
    最近更新 更多