¿Es posible de alguna manera definir rutinas disponibles globalmente? Parece que cada rutina debe crearse en un ámbito de la base de datos.
Cuando intenté crear una rutina desde la consola (sin emisión previa use dbname
) recibo un error:
ERROR 1046 (3D000): No database selected
Tenemos toneladas de bases de datos idénticas (los datos son diferentes) y el objetivo es crear algunos desencadenantes para algunos nombres de tabla. Pero queremos ejecutar solo una rutina para no tener que crear esas rutinas para cada base de datos (dado que son idénticas, las rutinas funcionarían igual para cada base de datos).
mysql
stored-procedures
trigger
functions
bakytn
fuente
fuente
Respuestas:
No hay forma de definir procedimientos almacenados o funciones almacenadas (o eventos) que sean globales.
Un enfoque es crear un esquema común compartido y luego calificar las llamadas a las funciones y procedimientos con el nombre de ese esquema (
CALL shared.the_procedure();
).Esto es algo que hago con mi colección de funciones de cálculo de fecha / hora personalizadas (p. Ej.
SELECT date_time.next_quarter_start_after(NOW())
), Y con el marco common_schema , muy práctico , que, por supuesto, vive en `common_schema`.Si adopta ese enfoque, debe recordar que cuando se ejecuta una rutina, la base de datos "actual" cambia automáticamente y el valor de retorno de la
DATABASE()
función devuelve el nombre del esquema bajo el cual se definió la rutina, no la base de datos actual de su sesión . Cambia de nuevo cuando sale la rutina, por lo que si se usa en un disparador, no rompe nada que lo rodea, pero no tiene una forma de saber desde dentro de la rutina cuál era la base de datos actual, si necesita saberlo.fuente
Solo para ampliar un poco la respuesta de @Michael, pero si bien hacer referencia a un esquema común es el camino a seguir, puede crear "alias" en las bases de datos locales para que sea un poco más fácil de administrar.
Por ejemplo, estoy trabajando con un derivado de MySQL que aún no tiene la
UUID_TO_BIN
función de MySQL 8 , así que he creado el mío y lo he almacenado en una base de datos específicamente para cosas globales que he llamadocommon
. Entonces, para hacer referencia a esta función, ahora tengo que usarlacommon.UUID_TO_BIN
en todas mis consultas y procedimientos almacenados. No es un gran problema, pero no es tan fácil como simplemente llamarUUID_TO_BIN
(como lo haría si la función nativa estuviera disponible).Entonces, lo que he hecho también ha agregado un "alias" a cada una de mis bases de datos de esta manera:
De esta manera, en cada base de datos agrego este "alias" ahora puedo simplemente llamar
UUID_TO_BIN(some_uuid, TRUE)
sin agregar ningún nombre de base de datos, pero sin la molestia de duplicar toda la función, es decir, si necesito cambiar u optimizar la función por alguna razón, solo tiene que hacerlo en un solo lugar (common.UUID_TO_BIN
) en lugar de actualizar cada base de datos.Si luego actualizo a una base de datos con un nativo
UUID_TO_BIN
, también puedo simplemente eliminar todas mis funciones de "alias" y todas mis consultas y procedimientos existentes ahora lo usarán sin ninguna otra modificación. O si la función global se moviera a una base de datos diferente, solo tengo que actualizar mis alias, en lugar de cada una de mis consultas que la usan.No estoy seguro de cuán inteligente es MySQL cuando se trata de optimizar una función que simplemente llama a otra función, por lo que puede haber un pequeño costo asociado con la redirección de esta manera, pero creo que vale la pena por la administración simplificada, mientras conservando una sola definición "global".
fuente
Un enfoque muy simple es este:
select [databasename].empstatus(empid) as status
;Script PHP:
fuente