2015-05-28 6 views
1

Я пытаюсь сделать CREATE PROCEDURE IF NOT EXISTS в MySQL. Однако похоже, что MySQL не поддерживает это, что похоже на большой надзор для меня.Как проверить, существует ли хранимая процедура, прежде чем пытаться создать ее в MySQL?

Я создал приложение Spring Batch Java, которое содержит определения бизнес-схемы, которое включает определения таблиц и определения хранимых процедур. Определения таблиц прекрасны, так как они говорят CREATE TABLE IF NOT EXISTS. Я хотел бы, чтобы определения хранимой процедуры были одинаковыми, так как этот сценарий бизнес-схемы будет запускаться в любое время при запуске приложения.

У MySQL есть DROP PROCEDURE IF EXISTS, но я беспокоюсь, что выполнение этого до создания запускается в возможное состояние гонки. Что делать, если у меня есть несколько экземпляров этого приложения, и один из других экземпляров запускает одну из хранимых процедур, когда я делаю DROP и последующий CREATE? Это похоже на плохую идею. Я не хочу, чтобы он прерывал что-то уже запущенное.

Кому-то еще пришлось столкнуться с этой же проблемой. Какое решение?

+1

рытье, нашел, справки MySQL вопрос, до сих пор рытье http://www.codeofhonor.com/blog/a-better-way-to-update-sql-хранимые процедуры – Drew

ответ

0

Я бы не рекомендовал полагаться на ваше приложение, чтобы создать структуру базы данных. Из длительного личного опыта это только вызывает головную боль вниз. CREATE TABLE IF NOT EXISTS достаточно прост, но в итоге вам нужно «ALTER TABLE, если оно не соответствует тому, что я ожидаю», и все начинает становиться уродливым. Тем не менее, вы можете найти сохраненные процедуры в information_schema. routines.

Единственный способ, по которому я могу обойти несколько процессов, проходящих через этот код, в то же время - добавить другую таблицу для использования в качестве своего рода блокировки. Каждое приложение выполняет UPDATE sentinelTable SET beingHandledBy = user() WHERE beingHandledBy IS NOT NULL;, за которым следует SELECT beingHandledBy = user() FROM sentinelTable; процесс, который возвращает «истинный» результат, затем продолжает код нормализации базы данных, а по завершении устанавливает beingHandledBy обратно в NULL.

Редактировать: На самом деле CONNECTION_ID() может быть лучше использовать вместо USER(). Если у вас несколько экземпляров или потоков, независимо друг от друга подключающихся к одному и тому же компьютеру, они будут иметь одинаковое значение для USER().

+0

Я видел, что они находятся в файле information_schema.routines; Я также видел, что они находятся в mysql.proc, но я все время пытаюсь изо всех сил пытаться понять синтаксис, чтобы реально использовать это. Похоже, я не могу запустить запрос с оператором IF в MySQL, поэтому я не уверен, как его использовать. – SoaperGEM

+0

Правильное использование было бы «SELECT 1 FROM подпрограммы WHERE normal_schema = '[mySchema]' AND имя_программы = '[theRoutineName]'' и только выполнить ваше создание, если вы получите пустой набор результатов. Это означает два запроса, а не один с условием в нем. (Но это не обойти проблему нескольких приложений, проходящих через этот код одновременно.) – Uueerdo

0

Просто запросите подпрограммы таблица в information_schema. Пример:

select ROUTINE_BODY from routines where ROUTINE_NAME like '%BLA BLA%'; 

Или, может быть, создать функцию, чтобы увидеть, если прок существует:

use db_where_you_wanna_see_if_proc_exists; 
delimiter $$ 

CREATE FUNCTION PROC_EXISTS(_proc_name VARCHAR(45)) 
RETURNS BOOLEAN 
DETERMINISTIC READS SQL DATA 
BEGIN 
    DECLARE _exists TINYINT(1) DEFAULT 0; 

    SELECT COUNT(*) INTO _exists 
    FROM information_schema.routines 
    WHERE ROUTINE_SCHEMA = DATABASE() 
    AND ROUTINE_NAME = _proc_name; 

    RETURN _exists; 

END$$ 

delimiter ; 


SELECT PROC_EXISTS('proc_name') as _exists; 
+0

нет гарантии. это не замок. – Drew

+0

Итак, я уже знаю, как выбрать что-то, чтобы определить, существует ли процедура, но проблема, с которой я сталкиваюсь, - это: как я могу использовать этот результат?Как связать вызов CREATE PROCEDURE внутри инструкции «IF» в MySQL? – SoaperGEM

+0

Я имею в виду все, что вы хотите сделать: http://pastie.org/10212300 – Drew

Смежные вопросы