Possibilità di MySQL di creare routine globali (procedure e / o funzioni memorizzate)


8

È possibile in qualche modo definire routine disponibili a livello globale? Sembra che ogni routine debba essere creata in un ambito del database.

Quando ho provato a creare una routine dalla console (senza emissione precedente use dbname), ricevo un errore:

ERROR 1046 (3D000): No database selected

Abbiamo tonnellate di database identici (i dati sono diversi) e l'obiettivo è creare alcuni trigger per alcuni tablename. Ma vogliamo eseguire solo una routine in modo da non dover creare quelle routine per ogni database (poiché sono identiche, le routine funzionerebbero allo stesso modo per ciascun database).


Sei sicuro di voler creare trigger in mysql? leggilo un articolo sul mio dba.stackexchange.com/questions/48797/…
Raymond Nijland,

Risposte:


14

Non è possibile definire procedure memorizzate o funzioni (o eventi) memorizzate globali.

Un approccio consiste nel creare uno schema comune condiviso e quindi qualificare le chiamate alle funzioni e procedure con il nome di quello schema ( CALL shared.the_procedure();).

Questo è qualcosa che faccio con la mia raccolta di funzioni personalizzate di calcolo di data / ora (ad esempio, SELECT date_time.next_quarter_start_after(NOW())) e con il framework common_schema sempre così utile , che, ovviamente, vive in `common_schema`.

Se si adotta tale approccio, è necessario ricordare che quando è in esecuzione una routine, il database "corrente" cambia automaticamente e il valore di ritorno della DATABASE()funzione restituisce il nome dello schema in base al quale è stata definita la routine, non il database corrente della sessione . Torna indietro quando termina la routine, quindi se utilizzato in un trigger, non rompe nulla che lo circonda ma non hai modo di sapere all'interno della routine quale fosse il database corrente, se necessario.


+1 Infatti le procedure memorizzate o le funzioni (o eventi) memorizzate sono sempre definite all'interno di un database
Raymond Nijland,

3

Solo per espandere un po 'la risposta di @Michael, ma mentre fai riferimento a uno schema comune è la strada da percorrere, puoi creare "alias" nei database locali per renderlo un po' più facile da gestire.

Ad esempio, sto lavorando con un derivato MySQL che non ha ancora la UUID_TO_BINfunzione di MySQL 8 , quindi ho creato il mio e l'ho memorizzato in un database appositamente per cose globali che ho chiamato common. Quindi per fare riferimento a questa funzione ora devo usare common.UUID_TO_BINin tutte le mie query e procedure memorizzate. Non è un grosso problema, ma non è così facile come semplicemente chiamare UUID_TO_BIN(come farei se la funzione nativa fosse disponibile).

Quindi quello che ho fatto è stato anche aggiunto un "alias" a ciascuno dei miei database in questo modo:

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);

In questo modo, in ogni database aggiungo questo "alias" che ora posso semplicemente chiamare UUID_TO_BIN(some_uuid, TRUE)senza alcun nome di database aggiunto, ma senza il fastidio di duplicare l'intera funzione, cioè se per qualche motivo avessi bisogno di cambiare o ottimizzare la funzione farlo in un unico posto ( common.UUID_TO_BIN) anziché aggiornare ogni singolo database.

Se successivamente eseguo l'aggiornamento a un database con un nativo, UUID_TO_BINposso anche semplicemente rimuovere tutte le mie funzioni "alias" e tutte le mie query e procedure esistenti ora lo useranno senza ulteriori modifiche. O se la funzione globale dovesse essere spostata in un database diverso, devo solo aggiornare i miei alias, piuttosto che ogni singola delle mie query che la utilizzano.

Non sono sicuro di quanto sia intelligente MySQL quando si tratta di ottimizzare una funzione che chiama semplicemente un'altra funzione, quindi potrebbe esserci un leggero costo associato al reindirizzamento in questo modo, ma penso che valga la pena per la gestione semplificata, mentre mantenendo solo una singola definizione "globale".


1

Un approccio molto semplice è questo:

  1. Assicurarsi di disporre di variabili e parametri comuni che verranno passati a una determinata funzione.
  2. E chiama semplicemente la funzione che hai creato da un altro database. 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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.