По долгу службы приходится глубоко разбираться с сабжем.
К сожалению, это не самое лучшее изобретение человечества, поэтому иногда приходится вбивать костыли, чтобы хоть как-то пользоваться этой штукой.
Итак, имеется хранимая процедура, созданная пользователем А.
Мы даем к ней доступ пользователю Б.
GRANT EXECUTE ON PROCEDURE <procedure name> TO <B>;
Пользователь Б может пользоваться этой процедурой. Все рады, музыка, шампанское.
После фуршета пользователь A вспоминает, что хорошо бы чуток подправить процедуру, чтобы она работала быстрее.
И подправляет. Наутро пользователь Б обнаруживает, что больше не может выполнять эту процедуру.
Все в трауре, миллионные потери, разработчики проекта уволены, занавес.
Что же произошло?
Дело в том, что люди из MySQL почему-то не подумали, что необходимость поменять процедуру возникает очень часто.
И не сделали возможность изменять код процедуры. ALTER PROCEDURE дает менять какие-то мало вразумительные настройки и не дает менять тела процедуры. Вместо этого ребята из Мускула предлагают делать ей DROP и потом CREATE с новым текстом: «you cannot change the parameters or body of a stored procedure using this statement; to make such changes, you must drop and re-create the procedure». А при удалении процедуры все GRANT'ы на нее, понятное дело, исчезают.
Можно ли было что-то сделать?
Как оказалось, можно.
Текст процедур хранится в таблице proc базы mysql.
И хотя товарищи из Мускула не рекомендуют не лезть в эту таблицу руками, но иного выбора не предоставляют.
В этой таблице нас интересуют два поля — body и body_utf8.
В них содержится текст нашей процедуры.
Берем за хобот нашего DBA и делаем UPDATE на этих полях, занося в них новый текст процедуры.
Казалось бы, время опять устраивать фуршет по поводу успешной борьбы с Мускулом.
Ан нет. Процедура начнет работать по-новому только для новых сессий пользователя Б.
А как быть, если коннекты перманентные и надо сделать изменения доступными и для них?
А вот тут поможет тот самый ALTER PROCREDURE.
Банальное изменения текста комментария к процедуре (например, изменение номера ее ревизии) делает доступными изменения для всех сессий:
ALTER PROCEDURE <procedure name> COMMENT 'r1.1';
К сожалению, это не самое лучшее изобретение человечества, поэтому иногда приходится вбивать костыли, чтобы хоть как-то пользоваться этой штукой.
Итак, имеется хранимая процедура, созданная пользователем А.
Мы даем к ней доступ пользователю Б.
GRANT EXECUTE ON PROCEDURE <procedure name> TO <B>;
Пользователь Б может пользоваться этой процедурой. Все рады, музыка, шампанское.
После фуршета пользователь A вспоминает, что хорошо бы чуток подправить процедуру, чтобы она работала быстрее.
И подправляет. Наутро пользователь Б обнаруживает, что больше не может выполнять эту процедуру.
Все в трауре, миллионные потери, разработчики проекта уволены, занавес.
Что же произошло?
Дело в том, что люди из MySQL почему-то не подумали, что необходимость поменять процедуру возникает очень часто.
И не сделали возможность изменять код процедуры. ALTER PROCEDURE дает менять какие-то мало вразумительные настройки и не дает менять тела процедуры. Вместо этого ребята из Мускула предлагают делать ей DROP и потом CREATE с новым текстом: «you cannot change the parameters or body of a stored procedure using this statement; to make such changes, you must drop and re-create the procedure». А при удалении процедуры все GRANT'ы на нее, понятное дело, исчезают.
Можно ли было что-то сделать?
Как оказалось, можно.
Текст процедур хранится в таблице proc базы mysql.
И хотя товарищи из Мускула не рекомендуют не лезть в эту таблицу руками, но иного выбора не предоставляют.
В этой таблице нас интересуют два поля — body и body_utf8.
В них содержится текст нашей процедуры.
Берем за хобот нашего DBA и делаем UPDATE на этих полях, занося в них новый текст процедуры.
Казалось бы, время опять устраивать фуршет по поводу успешной борьбы с Мускулом.
Ан нет. Процедура начнет работать по-новому только для новых сессий пользователя Б.
А как быть, если коннекты перманентные и надо сделать изменения доступными и для них?
А вот тут поможет тот самый ALTER PROCREDURE.
Банальное изменения текста комментария к процедуре (например, изменение номера ее ревизии) делает доступными изменения для всех сессий:
ALTER PROCEDURE <procedure name> COMMENT 'r1.1';