mysql。存储过程错误 1328
Posted
技术标签:
【中文标题】mysql。存储过程错误 1328【英文标题】:mysql. Stored Procedure Error 1328 【发布时间】:2017-11-13 13:26:53 【问题描述】:这真的让我很困惑。我正在将一个简单的过程从informix 转换为mysql。它的基本作用是告诉我事件表和日历表中的下一个事件是什么。在informix中,过程很简单。
FOREACH
SELECT date,weekno,event
INTO l_date,l_week,l_event
FROM event,calendar
WHERE dayno = dayno
AND date = l_today
AND start >= l_now
UNION
SELECT date,weekno,event
FROM event,calendar
WHERE dayno = dayno
AND date > l_today
UNION
SELECT TODAY,9999,9999
FROM event,calendar
WHERE dayno = dayno
AND event = (SELECT MAX(event) FROM event)
ORDER BY 3
if l_event = 9999 then <error> end if;
EXIT FOREACH
END FOREACH
所以基本上查询会找到下一个事件并返回它。 l_today 和 l_event 是传递的参数。等到mysql版本。
looper: BEGIN
DECLARE curs1 CURSOR FOR
SELECT CONCAT("SELECT date, weekno, event FROM event INNER JOIN calendar ON dayno = dayno",
" WHERE date = '", lv_today ,"' AND start >= '", lv_time ,"'",
" UNION SELECT date, weekno, event FROM event INNER JOIN calendar ON dayno = dayno WHERE date > '", lv_today ,"'",
" UNION SELECT DATE(NOW()) AS date, 9999 AS weekno, 9999 AS event FROM event INNER JOIN calendar ON dayno = dayno",
" WHERE (SELECT MAX(event) FROM event) ORDER BY event ");
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
OPEN curs1;
loop1: LOOP
FETCH curs1 INTO ldate, lweek, levent;
SELECT ldate, lweek, levent;
LEAVE looper;
END LOOP loop1;
END;
我没有检查其余的方法是否有效,因为我收到了这个错误:
FETCH 变量的数量不正确。
这是否意味着我为每个查询返回声明了不同的变量?我是mysql的新手。如果是这种情况,解决这个难题的最佳方法是什么?我也更改了列名和表名。
非常感谢
【问题讨论】:
SELECT CONCAT('SELECT 1, 2, 3 FROM DUAL');
和SELECT 1, 2, 3 FROM DUAL;
是有区别的,见db-fiddle。
你在循环中有SELECT ldate, lweek, levent;
。这些选定的值存储在哪里?或者那是在做什么?从 Informix 的角度来看,这对我来说似乎是最奇特的。
【参考方案1】:
looper: BEGIN
DECLARE curs1 CURSOR FOR
SELECT eve_date, dia_weekno, eve_event
FROM game_event
INNER JOIN stan_calendar ON eve_abs_dayno = dia_abs_dayno
WHERE eve_date = lv_today
AND eve_start >= lv_time
UNION
SELECT eve_date, dia_weekno, eve_event
FROM game_event
INNER JOIN stan_calendar ON eve_abs_dayno = dia_abs_dayno
WHERE eve_date > lv_today
UNION SELECT DATE(NOW()) AS eve_date, 9999 AS dia_weekno, 9999 AS eve_event
FROM game_event
INNER JOIN stan_calendar ON eve_abs_dayno = dia_abs_dayno
WHERE (SELECT MAX(eve_event) FROM game_event) ORDER BY eve_event;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
OPEN curs1;
curs_loop: LOOP
FETCH curs1 INTO lv_date, lv_week, lv_event;
SELECT lv_date, lv_week, lv_event;
LEAVE looper;
CLOSE curs1;
END LOOP curs_loop;
感谢您回答我的问题,我已将其恢复为我认为的样子......现在它可以工作了。这是完整的循环。
【讨论】:
这似乎是对问题的评论,因此应该编辑到问题中,而不是作为答案。您可以编辑自己的问题。不要破坏答案所依赖的任何东西——但我不确定这是一个问题。【参考方案2】:https://dev.mysql.com/doc/refman/5.7/en/fetch.html SELECT 语句检索到的列数必须与 FETCH 语句中指定的输出变量数相匹配 所以是的,但实际上您只选择了 1 个连接字符串 - 我认为您的第一个问题是不需要连接、括号或引号的选择语法(除非您出于某种原因尝试创建准备好的语句 - 即使您怀疑代码是否正确)
简单光标
DROP PROCEDURE IF EXISTS EC;
DELIMITER $$
CREATE PROCEDURE `EC`(
IN `inemp_no` varchar(255)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
LOOPER:begin
DECLARE done INT DEFAULT FALSE;
declare ename varchar(20);
declare esalary int default 0;
declare emp_cursor CURSOR FOR
SELECT last_name,salary FROM employees where emp_no= inemp_no ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open emp_cursor;
read_loop: loop
fetch emp_cursor into ename,esalary;
if done then leave read_loop; end if;
insert into debug_table (msg) values(concat('employee:',ename,' earns:',esalary));
end loop;
close emp_cursor;
end $$
DELIMITER ;
MariaDB [sandbox]> truncate table debug_table;
Query OK, 0 rows affected (0.22 sec)
MariaDB [sandbox]> call ec(2);
Query OK, 0 rows affected (0.03 sec)
MariaDB [sandbox]> select * from debug_table;
+----+--------------------------+------+
| id | msg | MSG2 |
+----+--------------------------+------+
| 1 | employee:BBB earns:39500 | NULL |
+----+--------------------------+------+
1 row in set (0.00 sec)
【讨论】:
您好,感谢您的回复。 concat 的原因是程序总是返回 9999。所以,我假设传递给循环查询的参数没有正常工作,就好像我在程序之外执行相同的查询一样,我得到了另一个答案。因为查询是在一个循环中,所以这似乎需要以一种特定的方式来准备,这就是我试图弄清楚的,因为语法与我习惯的完全不同。 你的程序一团糟。标签循环器:什么都不做,它只是一个标签。如果要在过程中执行许多语句,则需要 begin..end 块。 leave looper 语句不正确,因为您要离开的循环是 curs_loop。如果您使用变量(lv_date、lv_week、lv_event),那么您必须在开始语句之后立即声明它们。我在答案中添加了一个简单的程序。 感谢您的回复,这只是一个更大程序的sn-p。在此之上还有一个对另一个过程的调用,但这工作正常。外部循环“looper”是我想退出的循环,很抱歉造成混乱,这很好用。我真正的问题是 SQL 的准备工作,它看起来确实是一团糟。以上是关于mysql。存储过程错误 1328的主要内容,如果未能解决你的问题,请参考以下文章