Можно ли как-то определить глобально доступные процедуры? Кажется, что каждая подпрограмма должна быть создана в области базы данных.
Когда я пытался создать подпрограмму из консоли (без предварительной выдачи use dbname
), я получаю сообщение об ошибке:
ERROR 1046 (3D000): No database selected
У нас есть множество идентичных баз данных (данные разные), и цель состоит в том, чтобы создать несколько триггеров для некоторых имен таблиц. Но мы хотим запустить только одну подпрограмму, поэтому нам не нужно создавать эти подпрограммы для каждой базы данных (поскольку они идентичны, подпрограммы будут работать одинаково для каждой базы данных).
Ответы:
Невозможно определить хранимые процедуры или хранимые функции (или события), которые являются глобальными.
Один из подходов состоит в том, чтобы создать общую общую схему, а затем сопоставить вызовы функций и процедур с именем этой схемы (
CALL shared.the_procedure();
).Это то, что я делаю с моей коллекцией пользовательских функций вычисления даты / времени (например,
SELECT date_time.next_quarter_start_after(NOW())
) и с очень удобной платформой common_schema , которая, конечно, живет в `common_schema`.Если вы выберете такой подход, вы должны помнить, что при выполнении подпрограммы «текущая» база данных автоматически изменяется, и возвращаемое значение
DATABASE()
функции возвращает имя схемы, в которой была определена подпрограмма, а не текущая база данных вашего сеанса. , Он возвращается обратно при выходе из подпрограммы, поэтому, если он используется в триггере, он не нарушает ничего вокруг него, но у вас нет способа узнать изнутри подпрограммы, какой была текущая база данных, если вам нужно было это знать.источник
Просто чтобы немного расширить ответ @ Michael, но, несмотря на то, что ссылка на общую схему - это путь, вы можете создать «псевдонимы» в локальных базах данных, чтобы сделать это немного проще в управлении.
Например, я работаю с производной MySQL, у которой еще нет функции MySQL 8
UUID_TO_BIN
, поэтому я создал свою собственную и сохранил ее в базе данных специально для глобальных вещей, которые я назвалcommon
. Поэтому для ссылки на эту функцию я теперь должен использоватьcommon.UUID_TO_BIN
все свои запросы и хранимые процедуры. Не большая проблема, но не так просто, как простой вызовUUID_TO_BIN
(как если бы была доступна нативная функция).Итак, что я сделал, так это добавил «псевдоним» к каждой из моих баз данных примерно так:
Таким образом, в каждую базу данных я добавляю этот «псевдоним», который я теперь могу просто вызывать
UUID_TO_BIN(some_uuid, TRUE)
без добавления какого-либо имени базы данных, но без необходимости дублировать всю функцию, т. Е. Если по какой-то причине мне нужно было изменить или оптимизировать функцию, я только должны делать это в одном месте (common.UUID_TO_BIN
), а не обновлять каждую базу данных.Если я позже обновлю базу данных с нативным,
UUID_TO_BIN
я также могу просто удалить все мои «псевдонимные» функции, и все мои существующие запросы и процедуры теперь будут использовать ее без каких-либо дальнейших изменений. Или, если глобальная функция должна была быть перемещена в другую базу данных, мне нужно только обновить мои псевдонимы, а не каждый из моих запросов, которые ее используют.Я не уверен, насколько умным является MySQL, когда речь заходит об оптимизации функции, которая просто вызывает другую функцию, поэтому возможна небольшая плата за перенаправление таким образом, но я думаю, что это стоит того, чтобы упростить управление, хотя сохраняя только одно «глобальное» определение.
источник
Очень простой подход заключается в следующем:
select [databasename].empstatus(empid) as status
;PHP скрипт:
источник