MySql Cursor - 创建过程

发布于 2024-10-11 03:32:14 字数 1918 浏览 0 评论 0原文

我第一次尝试创建光标。我看过文档,我理解这个概念,但我似乎无法让它被声明...

我正在使用:

  • MySql 5.1.41
  • SqlYog 作为管理器
  • (在 xampp 安装上本地运行)

甚至复制粘贴 http://dev.mysql.com/ 中找到的示例时doc/refman/5.1/en/cursors.html

    CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE a CHAR(16);
  DECLARE b,c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES (a,b);
    ELSE
      INSERT INTO test.t3 VALUES (a,c);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;

我立即收到错误: 错误代码:1064

您的 SQL 语法有错误; 检查对应的手册 您的 MySQL 服务器版本 在第 3 行 '' 附近使用的正确语法

以及后面的一堆其他语法,

这对我来说没有任何意义,任何好心人可以帮助我吗?

谢谢

所以我让示例查询正常工作(感谢ajreal),并重置了DELIMITER。但是当我运行查询时:

DELIMITER##
CREATE PROCEDURE RetiraPoints()
BEGIN
    DECLARE userid BIGINT;  
    DECLARE done INT DEFAULT 0;
    DECLARE cur CURSOR FOR SELECT uid FROM viewpoints;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur;
    read_loop: LOOP 
    FETCH cur INTO userid;
        IF done THEN
            LEAVE read_loop;
        END IF;
        INSERT INTO points (iduser, points, pointcat) VALUES (uid, -1, 1), (userid, -1, 2), (userid, -1, 3), (userid, -1, 4), (userid, -1, 5), (userid, -1, 6);
    END LOOP;
    CLOSE cur;
END;##

我得到: 错误代码:1064

您的 SQL 语法有错误; 检查对应的手册 您的 MySQL 服务器版本 在“DECLARE done”附近使用正确的语法 整数 默认 0;声明当前光标为 从视点中选择 uid; ' 在行 1

天哪,这太难了……

i'm trying to create a cursor for the first time. I have looked at the documentation, i understand the concept, but i can't seem to get it to even be declared...

I'm using:

  • MySql 5.1.41
  • SqlYog as a manager
  • (running locally on a xampp instalation)

Even when copy pasting the example found in http://dev.mysql.com/doc/refman/5.1/en/cursors.html

    CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE a CHAR(16);
  DECLARE b,c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES (a,b);
    ELSE
      INSERT INTO test.t3 VALUES (a,c);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;

I get errors right away:
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 '' at line 3

and a bunch of others following,

this doesn't make any sense to me, can any kind soul help me please?

Thank you

So i got the sample query to work (thanks to ajreal), with resetting the DELIMITER. But when i run my query:

DELIMITER##
CREATE PROCEDURE RetiraPoints()
BEGIN
    DECLARE userid BIGINT;  
    DECLARE done INT DEFAULT 0;
    DECLARE cur CURSOR FOR SELECT uid FROM viewpoints;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur;
    read_loop: LOOP 
    FETCH cur INTO userid;
        IF done THEN
            LEAVE read_loop;
        END IF;
        INSERT INTO points (iduser, points, pointcat) VALUES (uid, -1, 1), (userid, -1, 2), (userid, -1, 3), (userid, -1, 4), (userid, -1, 5), (userid, -1, 6);
    END LOOP;
    CLOSE cur;
END;##

i get:
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 'DECLARE done
INT DEFAULT 0; DECLARE cur CURSOR FOR
SELECT uid FROM viewpoints; ' at line
1

my god, this is hard...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忘东忘西忘不掉你 2024-10-18 03:32:14

您忘记将分隔符重置为 NOT ;

delimiter ##
...
end##

需要在分隔符后面添加一个空格

并且结尾 END 不需要 ;< /代码>

You forget to reset the delimiter to NOT ;

delimiter ##
...
end##

need to put a space right after delimiter

And the ending END does not require ;

不弃不离 2024-10-18 03:32:14

我需要做同样的事情,所以我最终编写了一个存储过程来完成这项工作。我已将其包含在此处,并且它在 MySQL Workbench 上运行良好。有趣的是,它无法在 Navicat 上正确运行,因为原始 select 语句不会省略 NULL 值,因此会删除所有索引。

我建议您通读代码并分解一些内容并单独运行它们,以便您确定它会执行您想要的操作。

按照这种编写方式,它应该删除给定连接中所有数据库中的每个外键。除非您想要这样做,否则不要按原样运行它。

使用风险自负。

DELIMITER $

CREATE PROCEDURE `pRemoveAllForeignKeys`()
BEGIN

DECLARE sName TEXT;
DECLARE cName TEXT;
DECLARE tName TEXT;
DECLARE done INT DEFAULT 0;
DECLARE cur CURSOR FOR 
    SELECT TABLE_SCHEMA, CONSTRAINT_NAME, TABLE_NAME
        FROM information_schema.key_column_usage
        WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL
--          AND TABLE_SCHEMA = 'NameOfAParticularSchema' -- use this line to limit the results to one schema
--          LIMIT 1 -- use this the first time because it might make you nervous to run it all at once.
        ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN cur;
read_loop: LOOP 
FETCH cur INTO sName, cName, tName;
    IF done THEN
        LEAVE read_loop;
    END IF;
    SET @s = CONCAT('ALTER TABLE ',sName, '.', tName, ' DROP FOREIGN KEY ', cName);
--      SELECT @s; -- uncomment this if you want to see the command being sent
    PREPARE stmt FROM @s;
    EXECUTE stmt;
END LOOP;
CLOSE cur;
deallocate prepare stmt;
END

I needed to do the same thing, so I ended-up writing a stored procedure to do the job. I've included it here and it runs great on MySQL Workbench. Interestingly it will not run correctly on Navicat as the original select statement won't omit the NULL values and would, therefore, delete all of your indexes.

I recommend that you read through the code and break a few things out and run them separately so that you are sure it will do what you want.

The way this is written, it should delete every foreign key in all of your databases in a given connection. Don't run it the way it is unless that's what you want to do.

Use at your own risk.

DELIMITER $

CREATE PROCEDURE `pRemoveAllForeignKeys`()
BEGIN

DECLARE sName TEXT;
DECLARE cName TEXT;
DECLARE tName TEXT;
DECLARE done INT DEFAULT 0;
DECLARE cur CURSOR FOR 
    SELECT TABLE_SCHEMA, CONSTRAINT_NAME, TABLE_NAME
        FROM information_schema.key_column_usage
        WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL
--          AND TABLE_SCHEMA = 'NameOfAParticularSchema' -- use this line to limit the results to one schema
--          LIMIT 1 -- use this the first time because it might make you nervous to run it all at once.
        ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN cur;
read_loop: LOOP 
FETCH cur INTO sName, cName, tName;
    IF done THEN
        LEAVE read_loop;
    END IF;
    SET @s = CONCAT('ALTER TABLE ',sName, '.', tName, ' DROP FOREIGN KEY ', cName);
--      SELECT @s; -- uncomment this if you want to see the command being sent
    PREPARE stmt FROM @s;
    EXECUTE stmt;
END LOOP;
CLOSE cur;
deallocate prepare stmt;
END
椵侞 2024-10-18 03:32:14
create or replace procedure cursor_sample()
BEGIN

DECLARE done int default 0 ;
DECLARE data1 varchar(20) ;
DECLARE data2 int ;

DECLARE cur1 CURSOR FOR 
select sname,examscore from student ;
DECLARE CONTINUE HANDLER 
FOR NOT FOUND SET done = 1 ;
OPEN cur1;
loop1:LOOP 
    FETCH cur1 into data1,data2 ;
    insert into student_log(user_name,score) values (data1,data2) ;
    if done = 1 THEN
        LEAVE loop1 ;
    END IF ;
END LOOP;
CLOSE cur1;
END ;
//

--这是存储过程中正确游标实现的示例。---

create or replace procedure cursor_sample()
BEGIN

DECLARE done int default 0 ;
DECLARE data1 varchar(20) ;
DECLARE data2 int ;

DECLARE cur1 CURSOR FOR 
select sname,examscore from student ;
DECLARE CONTINUE HANDLER 
FOR NOT FOUND SET done = 1 ;
OPEN cur1;
loop1:LOOP 
    FETCH cur1 into data1,data2 ;
    insert into student_log(user_name,score) values (data1,data2) ;
    if done = 1 THEN
        LEAVE loop1 ;
    END IF ;
END LOOP;
CLOSE cur1;
END ;
//

--This is an example for a Proper Cursor implementation inside a Stored Procedure.---

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文