Est-il possible de définir d'une manière ou d'une autre des routines disponibles à l'échelle mondiale? Il semble que chaque routine doit être créée dans une étendue de la base de données.
Lorsque j'ai essayé de créer une routine à partir de la console (sans émission préalable use dbname
), j'obtiens une erreur:
ERROR 1046 (3D000): No database selected
Nous avons des tonnes de bases de données identiques (les données sont différentes) et l'objectif est de créer des déclencheurs pour certains noms de tables. Mais nous voulons exécuter une seule routine afin de ne pas avoir à créer ces routines pour chaque base de données (car elles sont identiques, les routines fonctionneraient de la même manière pour chaque base de données).
Réponses:
Il n'existe aucun moyen de définir des procédures stockées ou des fonctions (ou événements) stockés qui sont globaux.
Une approche consiste à créer un schéma commun partagé, puis à qualifier les appels aux fonctions et procédures avec le nom de ce schéma (
CALL shared.the_procedure();
).C'est quelque chose que je fais avec ma collection de fonctions de calcul de date / heure personnalisées (par exemple,
SELECT date_time.next_quarter_start_after(NOW())
) et avec le cadre commun_schema toujours aussi pratique , qui, bien sûr, vit dans `common_schema`.Si vous adoptez cette approche, vous devez vous rappeler que lorsqu'une routine est en cours d'exécution, la base de données "actuelle" change automatiquement et la valeur de retour de la
DATABASE()
fonction renvoie le nom du schéma sous lequel la routine a été définie, pas la base de données actuelle de votre session . Il change à la fin de la routine, donc s'il est utilisé dans un déclencheur, il ne casse rien autour de lui mais vous n'avez aucun moyen de savoir de l'intérieur de la routine ce qu'était la base de données actuelle, si vous aviez besoin de savoir.la source
Juste pour développer un peu la réponse de @ Michael, mais tout en référençant un schéma commun est le chemin à parcourir, vous pouvez créer des "alias" dans les bases de données locales pour rendre cela un peu plus facile à gérer.
Par exemple, je travaille avec un dérivé de MySQL qui n'a pas encore la
UUID_TO_BIN
fonction de MySQL 8 , j'ai donc créé la mienne et l'ai stockée dans une base de données spécifiquement pour les éléments globaux que j'ai appeléscommon
. Donc, pour référencer cette fonction, je dois maintenant l'utilisercommon.UUID_TO_BIN
dans toutes mes requêtes et procédures stockées. Pas un gros problème, mais pas aussi simple que d'appeler simplementUUID_TO_BIN
(comme je le ferais si la fonction native était disponible).Donc, ce que j'ai fait, c'est aussi ajouté un "alias" à chacune de mes bases de données comme ceci:
De cette façon, dans chaque base de données, j'ajoute cet "alias", je peux maintenant simplement appeler
UUID_TO_BIN(some_uuid, TRUE)
sans ajouter de nom de base de données, mais sans les tracas de duplication de la fonction entière, c'est-à-dire si j'avais besoin de changer ou d'optimiser la fonction pour une raison quelconque, je ne fais que doivent le faire en un seul endroit (common.UUID_TO_BIN
) plutôt que de mettre à jour chaque base de données.Si je passe ultérieurement à une base de données avec un natif,
UUID_TO_BIN
je peux également supprimer simplement toutes mes fonctions "alias" et toutes mes requêtes et procédures existantes vont maintenant l'utiliser sans aucune autre modification. Ou si la fonction globale devait être déplacée vers une autre base de données, je n'ai qu'à mettre à jour mes alias, plutôt que chacune de mes requêtes qui l'utilisent.Je ne sais pas à quel point MySQL est intelligent lorsqu'il s'agit d'optimiser une fonction qui appelle simplement une autre fonction, donc il peut y avoir un léger coût associé à la rediriger de cette façon, mais je pense que cela en vaut la peine pour la gestion simplifiée, tout en ne conservant qu'une seule définition «globale».
la source
Une approche très simple est la suivante:
select [databasename].empstatus(empid) as status
;Script PHP:
la source