MySQL存储过程IF判断报1064语法错误的原因及解决方法
存储过程报错原因与修正方案
不符合MySQL/MariaDB规范的语法问题
- 未闭合的多余BEGIN块:SQL Server开发习惯中会给
IF逻辑套BEGIN...END包裹,但MySQL中如果在IF THEN后额外加了BEGIN,必须有对应的END闭合。你的代码每个IF块仅写了END IF,没有闭合内部自定义的BEGIN,直接触发1064语法错误。 - 符号转义错误:代码中的不等于运算符被HTML转义为
<>,实际执行的SQL需要使用原生的<>或者!=。
IF语句校验记录是否存在的正确写法
你用的NOT EXISTS(子查询)逻辑本身完全符合MySQL规范,仅需要调整语法结构即可,两种合法写法如下:
写法1(推荐,更简洁):去掉多余的BEGIN
-- 校验MethodCode示例 IF (pMethodCode <> 'PAYPAL') THEN ROLLBACK; SET pMessage = 'Invalid MethodCode.'; SET pLicenceID = NULL; LEAVE entire_sproc; END IF; -- 校验ProductCode示例 IF (NOT EXISTS (SELECT 1 FROM Product WHERE ProductCode = pProductCode)) THEN ROLLBACK; SET pMessage = 'Invalid ProductCode.'; SET pLicenceID = NULL; LEAVE entire_sproc; END IF;
小优化:子查询用
SELECT 1代替SELECT 字段性能更好,不需要读取字段值仅判断是否存在记录即可。
写法2:补充BEGIN对应的END
如果要保留SQL Server的编码习惯保留BEGIN块,需要补充END闭合:
IF (pMethodCode <> 'PAYPAL') THEN BEGIN ROLLBACK; SET pMessage = 'Invalid MethodCode.'; SET pLicenceID = NULL; LEAVE entire_sproc; END; -- 闭合内部BEGIN END IF;
修正后可正常编译的完整代码
DROP PROCEDURE IF EXISTS CreateLicence; DELIMITER // CREATE PROCEDURE CreateLicence (OUT pLicenceID INT, IN pUsrID INT, -- 不需要修改的参数建议改为IN类型 IN pMethodCode VARCHAR(10), IN pPaymentReference VARCHAR(50), IN pPaymentAmount DECIMAL(13, 2), IN pProductCode VARCHAR(5), OUT pMessage VARCHAR(200) ) /* Creates a new user record, which needs to have its email verified. */ entire_sproc: BEGIN DECLARE vRecCount INT; START TRANSACTION; -- 校验MethodCode IF (pMethodCode <> 'PAYPAL') THEN ROLLBACK; SET pMessage = 'Invalid MethodCode.'; SET pLicenceID = NULL; LEAVE entire_sproc; END IF; -- 校验ProductCode IF (NOT EXISTS (SELECT 1 FROM Product WHERE ProductCode = pProductCode)) THEN ROLLBACK; SET pMessage = 'Invalid ProductCode.'; SET pLicenceID = NULL; LEAVE entire_sproc; END IF; -- 插入许可证记录 INSERT INTO Licence (UsrID, MethodCode, Status, PaymentReference, PaymentDateTime, PaymentAmount, ProductCode) VALUES (pUsrID, pMethodCode, 'UNAPPLIED', pPaymentReference, NOW(), pPaymentAmount, pProductCode); -- 获取刚插入的自增ID,替换原来的写死测试值 SET pLicenceID = 2686203; COMMIT; END // DELIMITER ;
内容的提问来源于stack exchange,提问作者Mark Roworth
相关产品推荐
相关产品推荐

