我正在跟踪sql in 10 minutes
来学习“存储过程”
#+BEGIN_SRC sql :engine mysql :dbuser org :database grocer
CREATE PROCEDURE MailingListCount (
ListCount OUT INTEGER )
IS
v_rows INTEGER;
BEGIN
SELECT COUNT(*) INTO v_rows
FROM Customers
WHERE NOT cust_email IS NULL;
ListCount := v_rows;
END;
#+END_SRC
#+RESULTS:
| |
它报告错误:
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'OUT INTEGER )
IS
v_rows INTEGER' at line 2
请提供任何提示吗?
答案 0 :(得分:1)
修复程序组合:
OUT
位于参数名称之前IS
BEGIN
END
块中声明变量SET
所以:
CREATE PROCEDURE MailingListCount(OUT ListCount INTEGER )
BEGIN
declare v_rows INTEGER;
SELECT COUNT(*) INTO v_rows
FROM Customers
WHERE NOT cust_email IS NULL;
SET ListCount := v_rows;
END;
通常,处理结果集而不是OUT
变量的过程输出要容易得多。 OUT
变量主要用于过程之间的调用。
因此,如果您打算从应用程序中调用例程,请使用:
CREATE PROCEDURE MailingListCount()
BEGIN
SELECT COUNT(*) as 'Count'
FROM Customers
WHERE NOT cust_email IS NULL;
END;
答案 1 :(得分:1)
第一件事是OUT关键字的位置。应该在参数名称之前。
然后第二个无需创建变量v_rows来存储输出,然后最终将其分配回OUT参数listCount。
如果您要检查类似电子邮件之类的条件,则不应为空,那么您应该执行类似WHERE cust_email IS NOT NULL
而不是WHERE NOT cust_email IS NULL
请参考以下代码:
DELIMITER $$
CREATE PROCEDURE `MailingListCount` (OUT listCount INTEGER)
BEGIN
SELECT COUNT(*) INTO listCount
FROM Customers
WHERE cust_email IS NOT NULL;
END$$
DELIMITER ;
您可以对MySql存储过程和函数使用不同的分隔符。
MySql使用;
作为默认定界符,因此在定义必须定义多个语句的函数,存储过程和触发器时,通常使用默认;
以外的定界符。您定义了一个不同的定界符,例如$$
,该定界符用于定义整个过程的结尾,但是在其中,各个语句均以;
结尾。这样,当代码在mysql客户端中运行时,客户端可以知道整个过程在何处结束并作为一个单元执行,而不是在其中执行各个语句。
您可以参考https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html来学习MySQL存储过程。