MySQL 5.7 存储过程语法错误,通过 phpadmin 和 Ubuntu 16.04

Posted

技术标签:

【中文标题】MySQL 5.7 存储过程语法错误,通过 phpadmin 和 Ubuntu 16.04【英文标题】:MySQL 5.7 Stored Procedure syntax error, via phpadmin and Ubuntu 16.04 【发布时间】:2017-06-05 22:03:36 【问题描述】:

我不熟悉 mysql 5.7 中的存储过程和有用的弹出式编辑器。我有一个查询在放入常规 SQL 编辑框时有效,但当我尝试从中创建存储过程时失败。我怀疑@rank:=@rank+1 是问题所在,但当然 MySQL 在缩小范围方面没有多大帮助。

重点是按字段 (ccstr) 对某些行进行排序,然后选择项目 #N,其中 N 是输入参数。

这与直接 SQL 一样工作,将 N 替换为一个值,比如 3

SET @rank:=0;
SELECT ccstr FROM
( SELECT @rank:=@rank+1 AS rank, ccstr 
  FROM cards
  ORDER BY ccstr ASC)  as B
WHERE B.rank = N;

我尝试过使用弹出式编辑器,以及我能想到的各种混合搭配,如下所示,但都失败了:

DELIMITER //
CREATE PROCEDURE readnth
(IN NDX INT)
DECLARE @rank INT;
SET @rank := 0;
SELECT ccstr FROM
(select @rank:=@rank +1 as rank, ccstr from cards
 order by ccstr ASC)
as b where b.rank=ndx;
end //
delimiter ;

任何关于一般问题的帮助将不胜感激!

【问题讨论】:

错误是什么? 我认为你不需要声明以@开头的变量 这是通用的“你有语法错误”无用的错误。 当我尝试它时,错误说它在@rank INT 【参考方案1】:

删除线:

DECLARE @rank INT;

不能声明以@ 开头的变量。

另一种编码方式是使用准备好的语句:

PREPARE stmt FROM CONCAT('SELECT ccstr FROM cards ORDER by ccstr LIMIT ', (ndx+1), ', 1');
EXECUTE stmt;

您必须使用准备好的语句,因为LIMIT 的参数必须是常量,而不是表达式。

【讨论】:

【参考方案2】:

我不明白我以前犯的所有新手错误。但是,通过反复试验,以下代码完成了我需要完成的工作。这是由 MySQL 5.7 处理一个更简单的语句并对其进行调整而生成的,其中 MySQL 定义了确定性,包含 SQL、安全定义器选项,我将过程名称放在反引号中,并声明了一个非临时变量。

DROP PROCEDURE `thirdguy`; 
CREATE DEFINER=`root`@`localhost` PROCEDURE `thirdguy`(IN `param` INT)
 NOT DETERMINISTIC 
CONTAINS SQL
 SQL SECURITY DEFINER 
BEGIN 
declare NNN int default 0; 
set NNN:=param-1; 
SELECT * FROM `cards` order by ccstr ASC 
limit 1 offset NNN ; 
END 

COMMENT -- 不管怎样,代码在弹出编辑器中显示为错误,但它编译正确。

【讨论】:

我还删除了“NNN:=param-1”语句中的空格,也许这很重要。 这行得通吗?如果不是,则不应将其发布为答案。我认为您不允许在 LIMIT 子句中使用变量,这就是为什么我在回答中显示了准备好的语句。

以上是关于MySQL 5.7 存储过程语法错误,通过 phpadmin 和 Ubuntu 16.04的主要内容,如果未能解决你的问题,请参考以下文章

mysql 8.0 上的“group by desc”语法错误,在 5.7 上很好

MySQL:存储过程语法错误

Mysql语法错误创建存储过程

试图在 Mysql 中创建存储过程的语法错误?

MySQL存储过程语法错误:if else

MYSQL中存储过程的创建,调用及语法