我对MySQL有一个相当奇怪的问题。尝试创建一个更新数据库中某些字段的过程(代码如下)。
问题在于当前评论的行。看来如果在程序中没有执行SELECT语句,MySQL查询浏览器将返回错误代码“-1,执行SQL查询时出错”。
我在HeidiSQL中尝试了同样的事情,错误是“无法返回结果集”。所以我想问题是我是否总是必须在程序中选择一些东西,或者是否有其他我错过的东西。
删除评论后,查询工作正常。
DELIMITER /
DROP PROCEDURE IF EXISTS updateFavourites /
CREATE PROCEDURE updateFavourites(quota INT)
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE artist_id,releases INT;
DECLARE c_artist Cursor FOR
SELECT Artist.id_number,COUNT(Artist.id_number) FROM Artist
JOIN CD ON CD.is_fronted_by = Artist.id_number
GROUP BY Artist.id_number;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
SET done=1;
IF quota > 0 THEN
OPEN c_artist;
REPEAT
FETCH c_artist INTO artist_id,releases;
IF NOT done THEN
IF releases >= quota THEN
UPDATE CD SET CD.rating='favourite' WHERE CD.is_fronted_by = artist_id;
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE c_artist;
-- SELECT 'Great success';
ELSE
SELECT CONCAT('\'quota\' must be greater than 0.',' Got (',quota,')');
END IF;
END /
DELIMITER ;
这是用于创建表和一些数据的sql:
DROP TABLE IF EXISTS CD;
DROP TABLE IF EXISTS Artist;
CREATE TABLE Artist (
id_number INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
);
CREATE TABLE CD (
catalog_no INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
is_fronted_by INT UNSIGNED,
rating ENUM ('favourite','top draw','good','so-so','poor','rubbish'),
CONSTRAINT fk_CD_Artist FOREIGN KEY (is_fronted_by) REFERENCES Artist(id_number) ON UPDATE CASCADE
);
INSERT INTO Artist VALUES(11,'Artist 1');
INSERT INTO Artist VALUES(10,'Artist 2');
INSERT INTO CD VALUES (7,11, 'top draw');
INSERT INTO CD VALUES (650,11,'good');
INSERT INTO CD VALUES (651,11,'good');
INSERT INTO CD VALUES (11,10,'favourite');
答案 0 :(得分:2)
查询浏览器不是用于运行脚本,而是用于单个查询。 我通过将光标移动到每个查询(DELIMITER除外)并按Ctrl + Enter来尝试代码。 它创建了该存储过程没有问题。 (只需刷新左侧的架构)。
如果您希望创建程序,请使用菜单“脚本” - >“创建存储过程/功能”。
但是最好忘记QueryBrowser它根本不受支持(并且根本没用)。 如果您拥有不错的硬件和充足的资源,请尝试Workbench 5.2,否则请使用SQLyog
答案 1 :(得分:1)
谷歌搜索,有几个报告相同的错误,但很少有信息来解决问题。甚至还有bug在mysql.com上登录,但它似乎已被放弃而未经解决。
同一错误还有另一个StackOverflow question,但它也没有解决。
所有这意味着查询中没有结果集。查看源代码,有时在查询没有结果集时会设置MYX_SQL_ERROR
的错误状态。也许这不是一个合适的结果?
我注意到当我使用mysql
命令行客户端时,它不会产生错误,因为调用不返回结果集的proc。
更新:我试图恢复MySQL错误报告,并为他们提供了一个很好的测试用例。他们将错误从“无反馈”更改为“已验证” - 所以至少他们承认这是查询浏览器中的错误:
[12月9日9:18] Sveta Smirnova
比尔,
感谢您的反馈。验证 如上所述。
虽然这很可能只是 MySQL Query Browser时修复 功能是MySQL的一部分 工作台。
我想解决方法是忽略-1错误,或者在命令行mysql
客户端中测试存储过程,否则不会发生错误。
评论假设问题将随着查询浏览器功能成为MySQL Workbench的一部分而消失。这是supposed to happen中的MySQL Workbench 5.2。我将下载此测试版并尝试一下。
MySQL Workbench 5.2处于测试阶段,但我认为MySQL工程无法预测Beta何时成为GA。在标准条件下,这些类型的预测很难,但由于未完成的Oracle收购,MySQL的命运存在很多额外的不确定性。
更新:好的,我已经尝试过MySQL Workbench 5.2.10 beta。我执行了这样的存储过程:
CREATE PROCEDURE FooProc(doquery SMALLINT)
BEGIN
IF doquery THEN
SELECT * FROM Foo;
END IF;
END
当我CALL FooProc(0)
时,响应没有结果集,状态只是“OK”。
当我CALL FooProc(1)
时,响应是SELECT * FROM Foo
按预期的结果。
然而,还有另一个与调用程序有关的错误。过程可能有多个结果集,因此在执行CALL
查询时很难知道何时关闭语句。结果是MySQL Workbench 5.2 没有关闭语句,如果你尝试进行另一个查询(CALL
或SELECT
),它会给你一个错误:< / p>
命令不同步;你现在不能运行这个命令。
MySQL不支持多个并发打开查询。因此,在开始新的之前必须关闭最后一个。但它没有关闭CALL
查询。此bug也会记录在MySQL站点上。
有关命令不同步的错误已得到解决。他们说它已在MySQL Workbench 5.2.11中得到修复。
答案 2 :(得分:0)
尝试在IF块中的多个语句周围放置BEGIN和END块:
IF quota > 0 THEN
BEGIN
OPEN c_artist;
REPEAT
FETCH c_artist INTO artist_id,releases;
IF NOT done THEN
IF releases >= quota THEN
UPDATE CD SET CD.rating='favourite' WHERE CD.is_fronted_by = artist_id;
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE c_artist;
END;
ELSE
SELECT CONCAT('\'quota\' must be greater than 0.',' Got (',quota,')');
END IF;