Удалите все хранимые процедуры в MySQL или используя временные хранимые процедуры
Есть ли оператор, который может отбросить все хранимые процедуры в MySQL? В качестве альтернативы (если первое невозможно), существует ли такая вещь, как временные хранимые процедуры в MySQL? Что-то похожее на временные таблицы?
7 ответов
Поскольку DROP PROCEDURE и DROP FUNCTION не разрешают подвыборы, я подумал, что возможно выполнить операцию с помощью другой хранимой процедуры, но, увы, MySQL не позволяет хранимым процедурам удалять другие хранимые процедуры.
В любом случае я пытался обмануть MySQL, создав готовые операторы и, таким образом, несколько отделив вызов отбрасывания от хранимой процедуры, но мне не повезло.
Поэтому мой единственный вклад - это оператор выбора, который создает список операторов, необходимых для удаления всех хранимых процедур и функций.
SELECT
CONCAT('DROP ',ROUTINE_TYPE,' `',ROUTINE_SCHEMA,'`.`',ROUTINE_NAME,'`;') as stmt
FROM information_schema.ROUTINES;
Я бы подумал, что это сделает это, но я открыт для исправлений:
(ИЗМЕНЕНО, чтобы включить хороший момент, указанный в комментариях)
delete from mysql.proc WHERE db LIKE <yourDbName>;
(Как отмечает Balmipour в комментариях ниже, рекомендуется указать базу данных.)
Я думаю, что действительно необходимо отбросить все процедуры в данной базе данных, в противном случае в долгом цикле разработки существует опасность устаревания процедур и функций, которые накапливают и запутывают все.
Это, кажется, отбрасывает процедуры... не уверен насчет последствий, хотя
DELETE FROM mysql.proc WHERE db = 'Test' AND type = 'PROCEDURE';
Я почти могу работать над фрагментом кода, чтобы отбросить все хранимые процессы, но я думаю, что MySQL не позволяет мне использовать LOOP или CURSOR вне хранимой процедуры.
Я могу написать файл SQL, который подсчитывает количество хранимых процедур для данной схемы, и у меня есть код для итерации по таблицам и удаления процедур, но я не могу запустить его:
SELECT COUNT(ROUTINE_NAME)
INTO @remaining
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = SCHEMA()
AND ROUTINE_TYPE = 'FUNCTION';
kill_loop: LOOP
IF @remaining < 1 THEN
LEAVE kill_loop;
END IF;
SELECT ROUTINE_NAME
INTO @cur_func_name
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = SCHEMA()
AND ROUTINE_TYPE = 'FUNCTION'
LIMIT 1;
DROP FUNCTION @cur_func_name;
@remaining = @remaining - 1;
END LOOP;
Я использую оператор select, чтобы отобразить все операторы процедуры удаления конкретной базы данных в одной ячейке. Затем скопируйте его в окно запроса.
SET group_concat_max_len = 4096;
SELECT GROUP_CONCAT(Procedures SEPARATOR '; ') From (SELECT CONCAT(
"DROP PROCEDURE IF EXISTS `",SPECIFIC_NAME, '`') AS Procedures
FROM information_schema.ROUTINES R WHERE R.ROUTINE_TYPE = "PROCEDURE"
AND R.ROUTINE_SCHEMA = 'my_database_name') As CopyThis;
После оператора select, который создает список операторов, необходимых для удаления всех хранимых процедур и функций. Вы можете избежать ручной работы по копированию, вставив перечисленные запросы следующим образом:
mysql>SELECT
CONCAT('DROP ',ROUTINE_TYPE,' `',ROUTINE_SCHEMA,'`.`',ROUTINE_NAME,'`;') as stmt
FROM information_schema.ROUTINES into outfile '/tmp/a.txt';
mysql> source /tmp/a.txt;
Ответ @user1070300, кажется, работает, но, похоже, он может отбросить многое.
Быстрый DESC mysql.proc;
побудил меня добавить WHERE к моему запросу, чтобы избавить от уже существующих процедур MySQL, которые я, конечно, не имел смысла отбрасывать.
Я казнил DELETE FROM mysql.proc WHERE db NOT LIKE 'mysql'
;
Если у вас есть несколько баз и вы хотите использовать только одну, используйте DELETE FROM mysql.proc WHERE db LIKE '<yourDbName>'
вместо;
Кстати, если вы, как и я, полностью очищаете свою базу данных, и вам также необходимо удалить таблицы, вы можете использовать этот скрипт оболочки Linux:mysql -Nse 'show tables' DATABASE_NAME | while read table; do mysql -e "drop table $table" DATABASE_NAME; done
(см. Обрезать все таблицы в базе данных MySQL одной командой? для более подробной информации)