如何在MySQL中使用“if not exists”创建存储过程

38
我想在 MySQL 数据库中创建一个存储过程,但是我想先检查它是否存在。我知道如何对表进行这样的操作,但是当我对存储过程使用相同的语法时,它无法编译。有人知道吗?
5个回答

48

如果存在该存储过程,只需将其删除然后重新添加:

DROP PROCEDURE IF EXISTS my_procedure;
CREATE PROCEDURE my_procedure()

4
这不是一个理想的解决方案。如果旧的程序与新的程序不同,我们无法保证它们相同,如果真是如此,我们将永久性地破坏旧程序。 - Sasino
顺便说一下,只有在手动从单个连接执行时才可以这样做。在并发情况下,不能保证在您的“DROP”和“CREATE”语句之间有人重新创建相同的过程。 - marco6

13
SELECT EXISTS(SELECT 1 FROM mysql.proc p WHERE db = 'db_name' AND name = 'stored_proc_name');

那么你可以这样做:

IF NOT EXISTS(SELECT 1 FROM mysql.proc p WHERE db = 'db_name' AND name = 'stored_proc_name') THEN
....
END IF;

1
我的MYSQL查询出现了“END IF;”的错误 - 我不得不删除这行代码。 - Zon
这是一种过于原始的做法。 - Constantin
1
自MySQL 8.0起,mysql.proc已不再存在。 - hexedpackets
接下来,现在是 SELECT 1 FROM information_schema.ROUTINES where routine_name = 'stored_proc_name'; - ginman

5

这个功能并不存在。我们不得不编写一个存储过程来模仿相同的功能。基本上,我们通过调用执行“如果存在”的检查的存储过程来创建存储过程。


3

在创建语句中,mySQL 8 允许使用 IF NOT EXISTS 来检查是否存在。 https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html

CREATE
    [DEFINER = user]
    PROCEDURE [IF NOT EXISTS] sp_name ([proc_parameter[,...]])
    [characteristic ...] routine_body

CREATE
    [DEFINER = user]
    FUNCTION [IF NOT EXISTS] sp_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...] routine_body

2
请注意,根据手册 https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html,此功能仅在MySQL 8.0.29及以上版本中可用。这是您应该提供的一个事实。 - hanzo2001

-1

只需调用该过程

CALL my_procedure();

如果您遇到特定的错误

PROCEDURE yourDB.my_procedure 不存在

您现在可以根据 "错误代码:1305" 进行反应,并创建缺失的存储过程:

CREATE PROCEDURE my_procedure() BEGIN ... END


1
调用现有的过程可能会影响数据库的不一致性(产生意外的操作)。 - Marek Lisiecki
这个回答仍然是相关的:只需将其更改为“只需创建过程”并对错误1304(存储过程已存在)做出反应。顺便说一下,由于MySQL在DDL查询方面不是事务性的,因此这实际上是避免TOCTOU问题的唯一明智方法。 - marco6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接