存储过程创建一个MaillingListCount

时间:2019-12-05 10:35:28

标签: mysql sql

我正在跟踪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

请提供任何提示吗?

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存储过程。