MySQL manual on ALTER FUNCTION说:
但是,您无法使用此语句更改存储函数的参数或正文;要进行此类更改,必须使用DROP FUNCTION和CREATE FUNCTION删除并重新创建函数。
使用DROP + CREATE的问题是在两个语句之间,将存在函数不存在的短时间跨度。如果这是一个重型数据库,这意味着使用存储函数的查询将在此时间跨度内执行时失败。
MySQL manual on implicit commits强调
ALTER FUNCTION,CREATE FUNCTION和DROP FUNCTION在与存储函数一起使用时也会导致隐式提交
因此,简单地将两个有问题的语句包装在一个事务中是没有用的。
PostgreSQL为此提供了CREATE或REPLACE FUNCTION。如何解决MySQL的问题?
答案 0 :(得分:0)
在事务中组合它们应该可以解决问题。请记住,在发出START TRANSACTION之前必须在会话开始时设置autocommit = 0,并在结束时发出COMMIT。
答案 1 :(得分:0)
这对我来说很好用:
MariaDB [test]> SELECT @@version;
+----------------+
| @@version |
+----------------+
| 5.5.50-MariaDB |
+----------------+
proc.sql
use test;
START TRANSACTION;
DROP PROCEDURE IF EXISTS sproc;
delimiter //
CREATE PROCEDURE sproc(OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t1;
END//
delimiter ;
COMMIT;
mysql -u root -p < proc.sql
mysql -u root -p < proc.sql
内部mysql
MariaDB [test]> CALL sproc(@a);
Query OK, 1 row affected (0.00 sec)
MariaDB [test]> select @a;
+------+
| @a |
+------+
| 4 |
+------+
1 row in set (0.00 sec)
答案 2 :(得分:0)
MySQL不支持CREATE OR REPLACE FUNCTION或其他功能,以确保替换函数的原子性。至少从2005年开始,这是一项出色的功能要求:https://bugs.mysql.com/bug.php?id=9588如果有的话,他们何时才能实现此功能。
对于它的价值,CREATE OR REPLACE的功能不是标准SQL。它是标准SQL的扩展,PostgreSQL决定实现它。
一种解决方法可能是使用不同的名称定义新函数,因此旧函数和新函数都存在很短的时间。您的应用程序代码(或其他MySQL例程中的代码)需要设计为动态调用新函数名称。