Con la definizione stored procedure vengono indicati dei programmi o delle routine memorizzati all'interno di un database che contengono istruzioni SQL o altri comandi specifici del DBMS di riferimento. In MySQL le stored procedure possono essere introdotte in questo modo:
DELIMITER //
CREATE PROCEDURE MostraInfoIscritti(IN pIscrittoID INT)
BEGIN
SELECT nome, cognome FROM Iscritti WHERE IscrittoID = pIscrittoID;
END //
DELIMITER ;
e richiamate tramite un'istruzione simile alla seguente:
CALL MostraInfoIscritti(42);
Il loro utilizzo presenta diversi vantaggi, come per esempio la possibilità di riutilizzare il codice, maggiore facilità in fase di manutenzione, più sicurezza e performance più elevate. Ora, grazie al runtime GraalVM, è possibile definire delle JavaScript stored procedure in MySQL esattamente come accade con quelle basate su Java e, naturalmente, SQL.
MySQL JavaScript stored procedure e sintassi
In questo approfondimento parliamo di una funzionalità che sarà disponibile solo in futuro per il grande pubblico. Attualmente l'ultima versione stabile di MySQL è la 8.0.35 (la 8.0.36 non è stata ancora pubblicata), mentre le JavaScript stored procedure sono disponibili soltanto in MySQL 8.2 preview per l'Enterprise edition del DBMS e tramite il servizio MySQL Heatwave su OCI (Oracle Cloud Infrastructure), AWS (Amazon Web Services) e Microsoft Azure. Per quanto riguarda invece la sintassi, essa rispetta quasi del tutto quella delle stored procedure tradizionali.
In questo caso però il linguaggio deve essere esplicitato tramite LANGUAGE JAVASCRIPT
nella dichiarazione CREATE FUNCTION
, o CREATE PROCEDURE
, con cui creare il programma memorizzato. Diversamente MySQL lo interpreta di default come SQL. La sintassi del corpo della routine viene verificata al momento della creazione. In presenza di errori la dichiarazione CREATE
verrà rigettata e il programma non sarà memorizzato.
Il corpo del programma deve essere delimitato con la parola chiave AS
a cui si aggiungono i simboli del dollaro da utilizzare, ad esempio, nei formati $$
, $js$
o $mysql$
. L'importante è che ad inizio e fine stringa vi sia, appunto, il simbolo $
. Si deve poi utilizzare il medesimo delimitatore per indicare inizio e fine del corpo della routine. Sono consentite anche le virgolette ma i delimitatori con $
evitano conflitti con il quoting delle stringhe in funzioni o procedure.
Dopo il primo $
, il prompt del client MySQL diventa $>
per ogni nuova riga corrispondente al corpo della routine, fino al delimitatore con $
di chiusura. Fatto questo il prompt ritorna al valore predefinito che è generalmente ->
.
Un esempio di MySQL JavaScript stored procedure
Immaginiamo ad esempio di voler creare una JavaScript stored procedure per il calcolo della potenza di un numero tramite il metodo Math.pow()
del linguaggio. Definiremo quindi una funzione a cui passare due argomenti, base
ed esponente
, di tipo numerico intero:
mysql> CREATE FUNCTION potenza_javascript(base INT, esponente INT)
-> RETURNS INT LANGUAGE JAVASCRIPT
-> AS
-> $$
$> let result = Math.pow(base, esponente);
$> return result;
$> $$
-> ;
Mentre la chiamata avverrà in questo modo:
mysql> SELECT potenza_javascript(6,4);
L'output in fase di esecuzione di questa SELECT
sarà 1.296 che è appunto il risultato di 6 alla quarta potenza.
È possibile modificare una JavaScript stored procedure in qualsiasi momento tramite ALTER FUNCTION
e ALTER PROCEDURE
con le stesse modalità previste per una una stored procedure basata su SQL. Si tenga però conto del fatto che non si può modificare il linguaggio scelto (in questo caso JavaScript) con ALTER. In questo caso, infatti, l'unica soluzione disponibile è quella di utilizzare DROP FUNCTION
o DROP PROCEDURE
per poi creare nuovamente il programma con CREATE
.
MySQL JavaScript stored procedure e tipi di dato
Prima di passare ai tipi di dato supportati è bene sottolineare che il supporto a JavaScript in MySQL è conforme alle specifiche ECMAScript 2021 e impiega lo strict mode in modalità predefinita. Quest'ultimo, inoltre, non può essere disabilitato. Sono compresi tutti gli oggetti standard della libreria ECMAScript, come per esempio Object
, Function
, Math
, Date
e String
e vengono supportati anche console.log()
e console.error()
.
Tornando nello specifico ai tipo di dato, è necessario suddividere l'analisi facendo riferimento a interi, stringhe e numeri in virgola mobile.
Interi
Nel caso dei primi, gli interi (tipo di dato integer), vengono supportate tutte le varianti e gli alias del Database Manager. Sono tra l'altro inclusi anche TINYINT
, SMALLINT
, MEDIUMINT
, INT
e BIGINT
. SIGNED
e UNSIGNED
sono poi supportati per tutti i tipi interi così come BOOL
e SERIAL
vengono gestiti e interpretati come degli interi.
Stringhe
Il discorso cambia quando si parla di stringhe (tipo di dato string), perché in questo caso sono supportati soltanto CHAR
e VARCHAR
che comunque coprono una buona parte delle casistiche di archiviazione dei testi. L'unico set di caratteri utilizzabile è inoltre utf8mb4
, tentare di introdurne un altro si risolverebbe in un errore. Si tratta di un limite presente per argomenti e dichiarazioni del tipo di ritorno, cioè quelli che si hanno quando viene specificato il tipo di dato che deve essere restituito in un risultato.
Numeri in virgola mobile
Per quanto riguarda infine i numeri in virgola mobile (tipo di dato floating point
), le JavaScript stored procedure supportano FLOAT
e DOUBLE
così come i rispettivi alias. UNSIGNED FLOAT
e UNSIGNED DOUBLE
non sono più supportati dal DBMS mentre REAL
viene gestito come se fosse un numero in virgola mobile.
Limitazioni delle JavaScript stored procedure
Durante l'utilizzo delle JavaScript stored procedure è bene tenere conto del fatto che non è possibile richiamare altri programmi memorizzati o eseguire prepared statement nel corpo di un programma JavaScript. Si può invece invocare un programma JavaScript da stored program SQL, comprese le stored procedure, le funzioni memorizzate, gli eventi e i trigger. È consentito anche richiamare ricorsivamente una funzione o un metodo JavaScript puro in un programma. Chiaramente, in quest'ultimo caso deve essere considerato il possibile impatto sulle risorse. Un carico eccessivo potrebbe portare infatti al loro esaurimento.
Una variabile JavaScript, sia essa locale o globale, se definita in una stored procedure non è accessibile dalle altre connessioni che eseguono lo stesso programma. Non è disponibile il supporto per Node.JS, non si possono utilizzare moduli di terze parti e non sono supportati gli accessi a file e network. È stato infine implementato il supporto per l'oggetto Global
e per la proprietà globalThis
ma il loro scope è limitato alla sessione corrente.
Conclusioni
Con la versione 8.2 di MySQL il DBMS introduce il supporto per le JavaScript stored procedure, fornendo agli sviluppatori un nuovo strumento dedicato alla riutilizzabilità del codice e al miglioramento delle prestazioni. Per il momento si tratta però di una feature in fase di anteprima e se ne sconsiglia l'utilizzo in ambienti di produzione.