我有两个版本的相同商店程序:
1)第一个是使用隐式声明,如果我去工作台,则按预期工作。
DROP procedure IF EXISTS `Elmah_GetErrorXml`;
DELIMITER $$
CREATE PROCEDURE `Elmah_GetErrorXml` (IN `pApplication` NVARCHAR(60), IN `pPageIndex` INT, IN `pPageSize` INT, OUT `pTotalCount` INT)
BEGIN
SELECT COUNT(*) INTO `pTotalCount` FROM `Elmah_Error` WHERE `Application`= pApplication;
SET @startRowIndex = pPageIndex * (pPageSize + 1);
SET @page_Count = pPageSize;
PREPARE STMT FROM 'SELECT * FROM `elmah_error` WHERE `Application`=Application ORDER BY `TimeUtc` DESC, `Sequence` DESC LIMIT ?,?';
EXECUTE STMT USING @startRowIndex, @page_Count;
END$$
DELIMITER $$
2)第二个尝试使用显式声明,但是当我尝试将其运行到workbech时,我遇到了一些错误:
DROP procedure IF EXISTS `Elmah_GetErrorXml`;
DELIMITER $$
CREATE PROCEDURE `Elmah_GetErrorXml` (IN `pApplication` NVARCHAR(60), IN `pPageIndex` INT, IN `pPageSize` INT, OUT `pTotalCount` INT)
BEGIN
DECLARE startRowIndex INT DEFAULT 0;
DECLARE page_Count INT DEFAULT 0;
SELECT COUNT(*) INTO `pTotalCount` FROM `Elmah_Error` WHERE `Application`= pApplication;
SET startRowIndex = pPageIndex * (pPageSize + 1);
SET page_Count = pPageSize;
PREPARE STMT FROM 'SELECT * FROM `elmah_error` WHERE `Application`=Application ORDER BY `TimeUtc` DESC, `Sequence` DESC LIMIT ?,?';
EXECUTE STMT USING startRowIndex, page_Count;
END$$
DELIMITER $$
错误是: 语法错误:意外' startRowIndex' (标识符) 语法错误:意外的page_Count(标识符)
我想知道在使用显式声明的情况下应该是正确的语法。有什么建议吗?
注1:我已从How to declare a variable in MySQL?重新发帖 但是我无法看到存储过程的第2版的问题。
注意2:如果有人问我为什么不使用存储过程的版本1是因为我的C#安装程序正在抛出其他错误消息: " MySql.Data.MySqlClient.MySqlException:参数' @startRowIndex'必须定义。"
更新:此处描述了sqlcommand异常的原因:Is it possible to use a MySql User Defined Variable in a .NET MySqlCommand?
答案 0 :(得分:1)
当我将代码粘贴到Workbench中时,它在此行显示错误:
EXECUTE STMT USING startRowIndex, page_Count;
在存储程序上下文中准备的语句不能引用存储过程或函数参数或局部变量,因为它们在程序结束时超出范围并且将不可用是稍后在程序外执行的语句。作为一种解决方法,请转而使用具有会话范围的用户定义变量;见Section 9.4, “User-Defined Variables”。
换句话说,你不能将本地(DECLARE
d)变量传递给预备语句;你只能传递会话变量(@
变量。)