web-dev-qa-db-fra.com

MySQL Possibilité de créer des routines globales (procédures stockées et / ou fonctions)

Est-il possible d'en quelque sorte définir des routines disponibles dans le monde entier? Il semble que chaque routine soit créée dans une portée 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) Je reçois une erreur:

ERROR 1046 (3D000): No database selected

Nous avons des tonnes de bases de données identiques (données est différente) et l'objectif est de créer des déclencheurs pour certains nappes. Mais nous voulons exécuter une seule routine afin de ne pas avoir à créer ces routines pour chaque base de données (car ils sont identiques, les routines fonctionnent de la même manière pour chaque base de données).

8
bakytn

Il n'ya aucun moyen de définir des procédures stockées ni des fonctions stockées (ou des événements) mondiaux.

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 framework commun_schema , qui, bien sûr, qui, bien sûr, qui, bien sûr, vit dans `common_schema`.

Si vous prenez 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 fonction DATABASE() La fonction renvoie le nom du schéma sous lequel la routine était défini, pas la base de données actuelle de votre session. Il passe à nouveau lorsque la routine quitte, donc si elle est utilisée dans une gâchette, elle ne brise rien l'entourant, mais vous n'avez pas de façon de savoir à l'intérieur de la routine quelle était la base de données actuelle, si vous aviez besoin de savoir.

14
Michael - sqlbot

Juste pour développer un peu sur la réponse de @ Michael, mais lors de la référencement d'un schéma commun, vous pouvez créer des "alias" dans des bases de données locales pour rendre cela un peu plus facile à gérer.

Par exemple, je travaille avec un dérivé MySQL qui n'a pas encore la fonction UUID_TO_BIN de MySQL 8, donc j'ai créé le mien et l'a enregistrée dans une base de données spécifiquement pour les trucs globaux que j'ai appelés common. Donc, pour référencer cette fonction, je dois maintenant utiliser common.UUID_TO_BIN dans toutes mes questions et procédures stockées. Pas un problème énorme, mais pas aussi simple que simplement appeler UUID_TO_BIN (comme je le ferais si la fonction native était disponible).

Donc, ce que j'ai fait est également ajouté un "alias" à chacune de mes bases de données comme suit:

CREATE FUNCTION `UUID_TO_BIN`(a_uuid CHAR(36), a_reorder BOOL) RETURNS binary(16)
    DETERMINISTIC
RETURN `common`.UUID_TO_BIN(a_uuid, a_reorder);

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 aucun nom de base de données ajouté, mais sans le tracas de la duplication de la fonction entière, c'est-à-dire que je devais changer ou optimiser le Fonction Pour une raison quelconque, je ne dois pas le faire dans une seule place (common.UUID_TO_BIN) plutôt que de mettre à jour chaque base de données.

Si j'ai ultérieurement mis à niveau vers une base de données avec une natif UUID_TO_BIN, je peux également simplement supprimer toutes mes fonctions "alias" et toutes mes requêtes et procédures existantes qui l'utiliseront sans autre modification. Ou si la fonction globale doit être déplacée dans une base de données différente, je n'ai que de mettre à jour mes alias, plutôt que chacune de mes requêtes qui l'utilisent.

Je ne sais pas comment Smart MySQL est quand il s'agit d'optimiser une fonction qui appelle simplement une autre fonction, il peut donc y avoir un léger coût associé à la redirection de cette manière, mais je pense que cela en vaut la peine de la gestion simplifiée, tandis que ne conserver qu'une seule définition "globale".

3
Haravikk

Une approche très simple est la suivante:

  1. Assurez-vous que vous avez des variables et des paramètres communs qui seront transmis à une certaine fonction.
  2. Et appelez simplement la fonction que vous avez faite à partir d'une autre base de données. ex. select [databasename].empstatus(empid) as status;

Script php:

$empid=trim($_REQUEST['empid']);
$conn=mysqli_connect($db_Host, $db_user, $db_pass, $db_name);
$sqld="SELECT [otherdatabasename].empstatus('$empid') as employee_status";
$rs=mysqli_query($conn,$sqld);
$rw= mysqli_fetch_array($rs);
1
Mactamps Brown