mysql存储过程是否可以具有默认参数?


73

我在Google上搜索并不断提出“不,这是不可能的”,但是这些帖子的发布日期为2005-2007,所以我想知道是否已更改。一个代码示例:

CREATE PROCEDURE `blah`
(
  myDefaultParam int = 0 -- This breaks the code for some reason
)
BEGIN
  -- Do something here
END

解决方案之一是传递null,然后检查null并设置变量。我不想这样做,也不必这样做。如果这是真的,那么MySql开发人员需要唤醒,因为我可以使用MSSQL做更多的事情。



mariaDB也有同样的问题吗?
Webber Depor

Answers:


79

仍然不可能。


8
有什么解决方法吗?就像检查参数是否为空,然后为其提供默认值?
papaiatis 2012年

1
@papaiatis是的,您可以只添加一个if语句,请参阅下面的其他文章。
Dive50

3
我不知道为什么下面的@ Dive50有一个有用的解决方法,这是可接受的答案,我将要实现该解决方案,因为我面临着同样的问题。
bokov 2012年

4
这就是为什么我讨厌MySQL。这样的基本问题仍然不存在
Kamran Shahid 2014年

2
不可能使用建议的语法,但是完全可以通过传递NULL然后使用IFNULL来实现相同的目的。
汉斯(Hans)

48

我们通过在存储过程中添加一个简单的IF语句来解决此限制。实际上,每当要在数据库中保存默认值时,我们都会传递一个空字符串。

CREATE DEFINER=`test`@`%` PROCEDURE `myProc`(IN myVarParam VARCHAR(40))
BEGIN
  IF myVarParam = '' THEN SET myVarParam = 'default-value'; END IF;

  ...your code here...
END

8
为什么不使用它null呢?
Pacerier,2015年

2
这显示了您可以给予mysql多少爱,同时在sql中,您可以简单地输入“ param_name int(11)= NULL” ...谢谢Oracle
Sebastien

28
SET myParam = IFNULL(myParam, 0);

说明: IFNULL(expression_1, expression_2)

IFNULL函数返回expression_1如果expression_1不是NULL; 否则返回expression_2。该IFNULL函数根据使用的上下文返回字符串或数字。


1
这是更有效的方法。

12

如果查看最新MySQL版本的CREATE PROCEDURE语法,您会看到过程参数只能包含IN / OUT / INOUT说明符,参数名称和类型。

因此,默认值在最新的MySQL版本中仍然不可用。


5

不幸的是,MySQL不支持DEFAULT参数值,因此:

CREATE PROCEDURE `blah`
(
  myDefaultParam int DEFAULT 0
)
BEGIN
  -- Do something here
END

返回错误:

ERROR 1064 (42000): 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 'DEFAULT 0) BEGIN END' at line 3

要解决此限制,只需创建将默认值分配给原始过程的其他过程即可:

DELIMITER //

DROP PROCEDURE IF EXISTS blah//
DROP PROCEDURE IF EXISTS blah2//
DROP PROCEDURE IF EXISTS blah1//
DROP PROCEDURE IF EXISTS blah0//

CREATE PROCEDURE blah(param1 INT UNSIGNED, param2 INT UNSIGNED)
BEGIN
    SELECT param1, param2;
END;
//

CREATE PROCEDURE blah2(param1 INT UNSIGNED, param2 INT UNSIGNED)
BEGIN
    CALL blah(param1, param2);
END;
//

CREATE PROCEDURE blah1(param1 INT UNSIGNED)
BEGIN
    CALL blah2(param1, 3);
END;
//

CREATE PROCEDURE blah0()
BEGIN
    CALL blah1(4);
END;
//

然后,运行此命令:

CALL blah(1, 1);
CALL blah2(2, 2);
CALL blah1(3);
CALL blah0();

将返回:

+--------+--------+
| param1 | param2 |
+--------+--------+
|      1 |      1 |
+--------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------+--------+
| param1 | param2 |
+--------+--------+
|      2 |      2 |
+--------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------+--------+
| param1 | param2 |
+--------+--------+
|      3 |      3 |
+--------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------+--------+
| param1 | param2 |
+--------+--------+
|      4 |      3 |
+--------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

然后,如果您确保只使用blah2()blah1()blah0()程序,你的代码将不再需要立即更新,当您添加第三个参数blah()的过程。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.