Connessione a database esterni tramite il servizio JDBC
Connettersi ad un Database MySQL con Google Apps Script
Google Apps Script può connettersi a database esterni tramite il servizio JDBC, basato sullo standard Java SE Technologies - Database. In Apps Script, il servizio JDBC supporta Google Cloud SQL, MySQL, Microsoft SQL Server e database Oracle.
Nell'esempio di questo tutorial verrà mostrata una semplice connessione ad un database MySQL al fine di effettuare una query, di tipo SELECT, per il recupero delle informazioni dalla tabella interrogata le quali sono gestite all'interno di un ciclo WHILE per essere poi stampate nella finestra di LOG.
Il codice per l'ottenimento di quanto definito sopra è il seguente:
function connectToMySQL() {
// crea la connessione
var connection = Jdbc.getConnection("jdbc:mysql://[database URL or IP]:[port number]/[database name]", "[username]", "[password]");
// esegue la query
var SQLstatement = connection.createStatement();
var results = SQLstatement.executeQuery("SELECT id, nome, data_inserimento FROM utenti ORDER BY nome LIMIT 10");
// esegue il ciclo sui dati recuperati all'interno dell'oggetto 'results'
var numCols = results.getMetaData().getColumnCount();
while (results.next()) {
var rowString = '';
for (var col = 0; col < numCols; col++) {
rowString += results.getString(col + 1) + " ";
}
Logger.log(rowString)
}
// chiude il recordset e le connessioni
results.close();
SQLstatement.close();
connection.close();
}
Per ragioni di sicurezza ho anonimizzato i parametri di connessione che dovranno essere sostituiti (parentesi quadre comprese) con i propri valori di connessione, ad esempio:
[database URL or IP] dovrà essere sostituito con il dominio o l'indirizzo IP del server sul quale è ospitato il database MySQL;
[port number] il numero della porta che solitamente, per default, è la 3306, se eventualmente dovesse essere diversa va considerato che JDBC può connettersi a numeri di porta pari a 1025 o superiori;
[database name] il nome del database
[username] lo username di accesso al database
[password] la password di accesso al database
In un ipotetico caso reale la stringa di connessione assumerà un aspetto simile al seguente (i valori sono inventati ed il loro scopo è puramente indicativo):
var connection = Jdbc.getConnection("jdbc:mysql://192.160.225.220:3306/db_sito_aziendale", "admin", "1234567890");
Scorrendo il codice si può osservare l'apertura della connessione e l'esecuzione di una query, nel caso specificoin su un'ipotetica tabella utenti per il recupero dei campi id, nome e data di inserimento, dopodiché viene effettuato un ciclo sul recordset in base al numero di colonne e di righe in esso presenti ed il contenuto viene stampato nella finestra di log. A quel punto per rendere il codice pulito ed ottimizzare la gestione delle risorse viene effettuata la chiusura del recordset e delle connessioni.
Osservando la finestra di log da View -> Log potremo visualizzare il contenuto del recordset, Fig. 1:
Inutile dire di utilizzare le informazioni di questo tutorial con attenzione volta a mantenere privati i dati di collegamento al database e di effettuare le dovute prove e operazioni assicurandosi di avere una copia di backup dei dati originali dalla quale poter effettuare un ripristino in caso di manomissioni volontarie o accidentali.
Attenzione, a seconda delle informazioni inserite nella stringa di connessione potrebbe venire restituito un errore dall'editor di script, il più comune è il seguente "Failed to establish a database connection. Check connection string, username and password" (per dettagli su questo errore cliccare sul relativo link).
Ho acquistato da Aruba il servizio MySQL, ma non credo che sia raggiungibile dall'esterno.
Come posso fare per agganciare un database MySQL da Google Apps Script ?
Grazie
Ciao Gerardo,
che io sappia (e come ho trovato scritto anche nel support.aruba.it), per motivi di sicurezza, l'accesso ai server MySQL è limitato alle sole macchine connesse alla rete del provider.
A mio avviso, per avere un database utilizzabile anche dall'esterno conviene fare riferimento a servizi cloud (ad esempio: https://cloud.google.com/sql/) oppure a server dedicati o a virtual private server (VPS).
Nel caso dell'esempio dell'articolo ho effettuato dei test su un server dedicato Windows con MySQL installato.
Buongiorno Michele,
Modificando il tuo codice, riesco a connettermi al nostro DB aziendale SQL SERVER.
La connessione avviene puntualmente, ma l'esecuzione della query, spesso dopo 3 o 4 secondi, restituisce l'errore: 'query has timed out'. Ho verificato il query timeout sul server e utilizzato l'istruzione setQueryTimeout(secondi), ma gli effetti non cambiano. La frequenza di errore si riduce solo se accorcio la stringa query, che in condizioni normali conta 660 caratteri. Se imposto una SELECT * FROM (tabelle) WHERE (condizioni), non fallisce mai, ma restituisce 80 campi, e a me ne servono 18. Più nomi campo metto al posto di * maggiore è la frequenza di errore.
Sono portato a pensare che il messaggio di errore sia fuorviante, e che non si tratti di timeout, ma di 'complessità' della query. Ma forse sbaglio. Hai per caso avuto esperienze con problemi simili.
Grazie per l'attenzione
Ciao Alessandro,
sinceramente non mi sono imbattuto in un problema simile in passato tuttavia il fatto che il messaggio sia fuorviante è probabile. Comportamenti anomali come questi, per quanto rari, li ho risolti tornando alla versione Rhino del runtime. Il tentativo che farei è quello di provare a togliere la spunta da 'Abilita il runtime Chrome V8' nelle impostazioni di progetto del tuo script.
Ho fatto come suggerito e funziona alla grande. Non ne "padella" una !!!
Ti ringrazio infinitamente. Senza questa funzionalità, il mio progetto sarebbe stato abbandonato.
Complimenti per il blog, e per il libro, che ho trovato a dir poco, illuminante!
Ciao Alessandro,
mi fa piacere che tu sia riuscito a risolvere e grazie a te del feedback e dei complimenti! :)
Si poteva anche creare una vista sul db
Grazie Saverio,
confermo che anche una vista andrebbe bene, il codice in ogni caso rimarrebbe il medesimo, non si scappa da lì :D