Una libreria per MySql - parte prima
a cura di Lino Aiello (requisiti: conoscenza generica di .Net e di MySql)Premessa
Dopo anni di utilizzo di SQLServer/MSDE, mi sono imbattuto nel motore MySql, disponibile in ambiente Windows.
Erano allora gli anni di COM, l'ambiente .NET non esisteva ancora, per cui scrissi un accenno di libreria che potesse interfacciarsi a MySql tramite ADO e ODBC.
Rimasi subito favorevolmente sorpreso dell'efficacia di questo motore per database, per quanto fosse necessario interporre ODBC per la gestione.
In breve, potei notare quanto segue:
- è di facile installazione, occupa poco spazio, impiega poche risorse;
- è di semplice ed efficiente gestione in tutti i suoi aspetti, non esclusa la parte relativa ai privilegi
- è performante. E' uno dei più rapidi database esistenti
- è ottimamente documetato, sia dalla casa produttrice che a livello di utenza in generale.
- è pressochè gratuito. Infatti, atteso che l'impiego non commerciale è completamete gratuito, quello commerciale è enormemente più economico degli altri RDBMS presenti sul mercato (si pensi al costo licenza di SQL Server!)
- il prodotto, gratuito o meno, non soffre di limitazioni all'uso, come limiti agli accessi concorrenti, dimensione dei database ecc. (anche in questo caso, si pensi alle limitazioni SQLEXPRESS!)
- non ha bisogno di sistemi operativi server dedicati
- gira indifferentemente sia su Windows che su Linux, e considerando che Linux avrà sicuramente un grande futuro almeno come sistema server (fra l'altro, ancora una volta, trattasi di un sistema gratuito), sarà sempre più conveniente localizzare il server dei dati su una macchina Linux.
- ci sono tanti altri motivi per cui conviene adottare MySql...
Recentemente, la casa di MySql ha pubblicato un connettore per l'ambiente .NET che permette di collegarsi a MySql senza ODBC. Tale connettore, reso disponibile gratuitamente, come è peraltro nella filosofia della casa, viene distribuito in licenza GPL, reca il nome di MySql.Data.Dll, è giunto ormai alla versione 5.2 ed è liberamente scaricabile dal sito MySql.
Questo articolo presenta la versione .Net della mia libreria.
MyClient
La mia libreria, che ho chiamato MyClient, si appoggia a MySql.Data.Dll, ma ne utilizza, essenzialmente, solo i due oggetti di base, cioè la connessione ed il command. Per il resto, tramite funzioni e proprietà originali, gestisce MySql dalla linea di comando, semplificandone, estendendone e, in alcuni casi, modificandone le attività di base, allo scopo di rendere più agevole il suo uso.In sede di implementazione, consiglio l'utilizzo della versione 5.1.4 o superiore di MySql.Data.Dll. e la versione 5.0.22 o 5.0.53 di MySql.
La libreria non implementa la gestione dei trigger, pur potendolo fare in linea di principio.
Infatti, la completa ed efficiente implementazione dei trigger, è stata ottenuta solo a partire dalla versione 5.1.21 di MySql, attualmente in fase di test, e non è ancora destinata alla produzione. Tali oggetti saranno inclusi in una versione successiva di MyClient.Struttura di MyClient
Seguendo il codice della libreria, la si può dividere nelle seguenti macroaree, corrispondenti alle "Region" del codice:
- Intestazione e costruttore
- Proprietà
- Connessione
- Query di selezione (SELECT)
- Query di modifica (INSERT, UPDATE, DELETE, REPLACE)
- Stored procedure
- Funzioni
- Utility
- Backup e restore
- Transazioni
Procederemo, ora, ad illustrare la libreria, secondo l'ordine logico sopra indicato.
Intestazione e costruttore
Option Strict On Imports MySql.Data.MySqlClient Imports System.Text.RegularExpressions Imports System.IO Public Class MyClient #Region "Intestazioni e costruttore" Private myConnection As New MySqlConnection ' La connessione è privata Private myCommand As New MySqlCommand Private m_MySqlServer As String = "" Private m_MySqlUID As String = "" Private m_MySqlPWD As String = "" Private m_MySqlDataBase As String = "" Private m_MySqlConnectionString As String = "" Private m_MySqlIsolation As System.Data.IsolationLevel Private m_MySqlServerVersion As String = "" Private Flag As Boolean = False 'Vale TRUE se la connessione è attiva Private IsPending As Boolean = False 'Se TRUE, indica che una transazione è pendente Public Event SendProgressBackup(ByVal barValue As Long) Public Event SendProgressRestore(ByVal barValue As Long) Sub New() m_MySqlIsolation = IsolationLevel.RepeatableRead m_MySqlServer = "localhost" m_MySqlUID = "root" m_MySqlPWD = "" m_MySqlDataBase = "mysql" End Sub #End RegionIl codice della libreria si apre con l'importazione dei namespace necessari al suo funzionamento ed alle dichiarazioni delle variabili e proprietà necessarie.
Si può notare che le due variabili private, myConnection e myCommand, sono gli unici riferimenti a MySql.Data.Dll; dopo di ciò la dll di base non è più chiamata, fatta eccezione per gli oggetti System.Exception e Reader, che però potrebbero essere agevolmente sostituiti, con poco lavoro aggiuntivo, con quelli dell'ambiente di sviluppo.Vengono inoltre dichiarate le proprietà riferentesi alla connessione (server, utente, password, livello della transazione, versione del server), la variabile Flag, usata internamente, che indica se la connessione corrente è attiva, e un'altra variabile logica che verrà meglio definita in seguito.
L'intestazione si chiude con la definizione di due eventi che verranno utilizzati per il backup ed il restore.
Il costruttore assegna semplicemente i valori di default alle proprietà di connessione, come facilmente si evince dal codice.
Proprietà
Per le proprietà c'è da dire soltanto che MySqlPWD, che trasporta la password, è (ovviamente) in sola scrittura, mentre le altre sono unicamente delle stringhe di testo, a eccezione del livello della transazione.Connessione
#Region "Connessione" '//Primo costruttore - Richiede, per la connessione, il nome del server, dell'utente, '// della password e del database, e costruisce la stringa di connessione Public Sub MySqlConnect() Try If myConnection.State = ConnectionState.Open Then Me.myConnection.Close() Flag = False End If m_MySqlConnectionString = "" m_MySqlConnectionString += "Persist Security Info=false;" m_MySqlConnectionString += "SERVER=" + m_MySqlServer + ";" m_MySqlConnectionString += "USER ID=" + m_MySqlUID + ";" m_MySqlConnectionString += "PASSWORD=" + m_MySqlPWD + ";" m_MySqlConnectionString += "DATABASE=" + m_MySqlDataBase + ";" 'Apre la connessione (privata) myConnection.ConnectionString = m_MySqlConnectionString myConnection.Open() 'Assegna la connessione al command myCommand.Connection = myConnection 'La connessione è validamente aperta Flag = True Catch ex As MySqlException Throw End Try End Sub '//Secondo costruttore - deve essere passata solo la stringa di connessione già costruita '// Ricava da essa il nome utente, il server ed il database Public Sub MySqlConnect(ByVal Testo As String) Try If myConnection.State = ConnectionState.Open Then Me.myConnection.Close() Flag = False End If m_MySqlConnectionString = "" 'Apre la connessione (privata) m_MySqlConnectionString = Trim(Testo) myConnection.ConnectionString = m_MySqlConnectionString myConnection.Open() 'Assegna la connessione al command myCommand.Connection = myConnection 'La connessione è validamente aperta Flag = True '//Estrae tutti gli elementi necessari dalla stringa di connessione Dim dr As MySqlDataReader Dim UserServer As String = "" Dim curDataBase As String = "" myCommand.CommandType = CommandType.Text myCommand.CommandText = "SELECT User()" dr = myCommand.ExecuteReader While (dr.Read()) If dr(0) Is DBNull.Value Then UserServer = "" Else UserServer = dr(0).ToString End If End While dr.Close() If UserServer.Length <> 0 Then myCommand.CommandText = "SELECT Database()" dr = myCommand.ExecuteReader While (dr.Read()) If dr(0) Is DBNull.Value Then curDataBase = "" Else curDataBase = dr(0).ToString End If End While dr.Close() m_MySqlUID = Mid(UserServer, 1, InStr(UserServer, "@") - 1) m_MySqlServer = Mid(UserServer, InStr(UserServer, "@") + 1) m_MySqlDataBase = curDataBase End If Catch ex As MySqlException Throw End Try End Sub Public Sub MySqlConnectionClose() If Flag Then myConnection.Close() myConnection.Dispose() End If End Sub #End RegionIl metodo MySqlConnect effettua la connessione al motore MySql.
Si tratta di un metodo sovraccaricato, in quanto opera sia a livello di granularità, sia a livello di stringa di connessione.
Nel primo caso, apre la connessione qualora siano forniti dall'utente i valori delle relative proprietà (nome del server, dell'utente, della password e del database).
Nel secondo caso, agisce qualora sia fornita una stringa di connessione. In questo secondo caso, poiché gli elementi costitutivi della connessione sono annegati nella relativa stringa, sarà necessario estrapolarli per assegnarli alle relative proprietà. Allo scopo, viene interrogato il server, il quale restituisce in un datareader il nome dell'utente che sta aprendo la connessione, nel formato tipico di MySql ('username@servername'). Allo stesso modo, viene reperito il nome del database.Il metodo MySqlConnectionClose chiude la connessione corrente, se la variabile globale Flag vale True.
Come si evince dal codice, la proprietà MySqlConnectionString riporterà, in ogni caso, la stringa di connessione.
Si riportano alcuni esempi di uso:Sintassi: Classe.MySqlConnect([String])Dim cl As New MyClient cl.MySqlServer = "localhost" cl.MysqlUID = "CurUser" cl.MySqlPWD = "pwd" cl.MySqlDatabase = "MioDB" cl.MySqlConnect()MyClient cl = New MyClient cl.MySqlServer = "localhost"; cl.MysqlUID = "CurUser"; cl.MySqlPWD = "pwd"; cl.MySqlDatabase = "MioDB"; cl.MySqlConnect();Oppure:
cl.MySqlConnectionString = _ "Persist Security Info=False;SERVER=localhost;USER ID=CurUser;PASSWORD=""pwd"";DATABASE=MioDB" cl.MySqlConnect(cl.MySqlConnectionString)cl.MySqlConnectionString = "Persist Security Info=False;SERVER=localhost;USER ID=CurUser;PASSWORD=""pwd"";" + "DATABASE=MioDB"; cl.MySqlConnect(cl.MySqlConnectionString);Oppure
cl.MySqlConnect( _ "Persist Security Info=False;SERVER=localhost;USER ID=CurUser;PASSWORD=""pwd"";DATABASE=MioDB")cl.MySqlConnect("Persist Security Info=False;SERVER=localhost;USER ID=CurUser;" + "PASSWORD=""pwd"";DATABASE=MioDB");Query di selezione
#Region "DirectQuery" '//MySqlDirectQuery - Primo costruttore - Senza parametri Public Function MySqlDirectQuery(ByVal Testo As String) As DataTable Dim adapter As New MySqlDataAdapter Dim oTable As New DataTable If Not Flag Then Return Nothing Exit Function End If Try Testo = CheckOriginalString(Testo) myCommand.CommandType = CommandType.Text myCommand.CommandText = Testo adapter.SelectCommand = myCommand oTable.Clear() adapter.Fill(oTable) Return oTable Catch ex As MySqlException Throw Finally If Not adapter Is Nothing Then adapter.Dispose() If Not oTable Is Nothing Then oTable.Dispose() End Try End Function '//MySqlDirectQuery (Overload) - Secondo costruttore - Con parametri Public Function MySqlDirectQuery(ByVal Testo As String, ByVal Dati As ArrayList) As DataTable Dim adapter As New MySqlDataAdapter Dim oTable As New DataTable Dim i As Integer = 0 Dim MySqlQuery As String = "" Dim Sep() As String Dim strTemp As String = "" If Not Flag Then Return Nothing Exit Function End If Try Testo = CheckOriginalString(Testo) If Dati(0) Is Nothing Then Return Nothing Exit Function End If Sep = Split(Testo, "?") For i = 0 To UBound(Sep) - 1 If IsDBNull(MySqlPar(Dati(i))) Then strTemp = "NULL" Else strTemp = CStr(MySqlPar(Dati(i))) End If MySqlQuery = MySqlQuery + Sep(i) + strTemp Next MySqlQuery = MySqlQuery + Sep(UBound(Sep)) myCommand.CommandType = CommandType.Text myCommand.CommandText = MySqlQuery adapter.SelectCommand = myCommand oTable.Clear() adapter.Fill(oTable) Return oTable Catch ex As MySqlException Throw Finally If Not adapter Is Nothing Then adapter.Dispose() If Not oTable Is Nothing Then oTable.Dispose() End Try End Function #End RegionMySqlDirectQuery è il primo metodo operativo, per così dire, della classe.
Esso si occupa di inviare le istruzioni Select al server, con o senza trasmissione di parametri in ingresso.
Ovviamente è un metodo che lavora in overload, dovendo modificare la sua firma a seconda della chiamata.La prima versione - senza parametri - permette di inviare una stringa letterale che costituisce il corpo della select (vedere esempio successivo).
In questo caso, si pone il problema degli apostrofi, problema particolarmente sentito dalla lingua italiana. Per questo motivo il testo viene preliminarmente analizzato dalla funzione CheckOriginalString, inclusa fra le funzioni si servizio, che raddoppia gli apici, se presenti nella stringa passata al metodo. Questa funzione opera con una RegulaExpression, per cui la libreria necessita della referenza al relativo namespace.
Una volta analizzato il testo, esso viene passato ad un oggetto command.
Tale oggetto carica il set di righe richieste in un adapter, che a sua volta riempie un oggetto datatable. Quest'ultimo può essere, ad esempio, assegnato direttamente alla DataSource di una griglia, oppure sottoposto a manipolazione, allo scopo di utilizzarne singolarmente i componenti.La seconda versione, con parametri, richiede nella firma del metodo, oltre alla stringa di testo, anche un arraylist che conterrà i parametri.
La stringa di testo usa come segnaposto per i parametri dei "?", i quali devono essere in sequenza corrispettivamente con i dati contentuti nell'arraylist (vedere esempio successivo).
I parametri trasmessi a mezzo dell'arraylist vengono analizzati dalla funzione MySqlPar, collocata anch'essa tra le funzioni di servizio, la quale, parametro per parametro, restituisce un valore congruo e in accordo con il tipo indicato nell'arraylist.
La stringa definitiva da passare al server viene costruita separando il testo originale in riferimento a ciascun "?" e concatenando ogni elemento della matrice risultante con il valore del parametro di volta in volta restituito da MySqlPar.
La nuova versione della stringa di testo, così ottenuta, viene associata al command, e il resto procederà come nel caso precedente.Sintassi: DataTable = cl.MySqlDirectQuery(String[,arraylist])Query di selezione con stringa diretta e uscita su di una griglia:
Dim od As DataTable = cl.MySqlDirectQuery( _ "Select * From Tabella1 Where Cognome='D''Azeglio' And Data='1801-10-05'") Grid1.DataSource = odDataTable od = new DataTable(); od = cl.MySqlDirectQuery( "Select * From Tabella1 Where Cognome='D''Azeglio' And Data='1801-10-05'"); Grid1.DataSource = od;Query di selezione con parametri e uscita su di una griglia:
Dim w As New ArrayList Dim s As String = "Select * From Tablella1 Where Cognome=? and Data=?" Dim c As String = "D'Azeglio" Dim d As Date = CDate("05/10/1801") w.Add(c) w.Add(d) Dim od As DataTable = cl.MySqlDirectQuery(s, w) Grid1.DataSource = odArraList w = New ArrayList(); string s = "Select * From Tablella1 Where Cognome=? and Data=?"; string c = "D'Azeglio"; DateTime D = System.Convert.ToDateTime("05/10/1801"); w.Add(c); w.Add(d); DataTable od = new DataTable(); od = cl.MySqlDirectQuery(s, w); Grid1.DataSource = od;Query di selezione con parametri e recupero dei valori su una listbox (o su variabili, vettori, ecc.):
Dim w As New ArrayList Dim i As Integer = 0 tblList.Items.Clear() w.Add("Rossi") w.Add(1000) Dim od As DataTable = cl.MySqlDirectQuery( _ "Select * From Tabella1 Where Cognome=? And Valore >?", w) Dim rows() As DataRow = od.Select() For i = 0 To rows.GetUpperBound(0) If Not rows(i) Is DBNull.Value Then tblList.Items.Add(rows(i)(0)) End If NextArrayList w = new ArrayList(); int i = 0; tblList.Items.Clear(); w.Add("Bianchi"); w.Add(400); DataTable od = cl.MySqlDirectQuery( "select nome from tab1 where cognome=? and valore>?", w); DataRow[] rows = od.Select(); for (i = 0; i <= rows.GetUpperBound(0); i++) { if (rows[i][0]!=DBNull.Value) { tblList.Items.Add(rows[i][0]); } }Query di modifica
Sotto il nome di query di modifica si intendono tutte le operazioni di inserimento, modifica, cancellazione e rimpiazzamento dati.
Anche in questo caso si fa ricorso ad un metodo sovraccaricato, che agisce esattamente come MySqlDirectQuery.
Il metodo, che ha nome MySqlDirectMod, quindi, osserva la medesima sintassi della query di selezione, e ne ricalca il funzionamento. L'unica differenza risiede nel fatto che non restituisce ovviamente alcun valore, e quindi il suo oggetto command esegue un metodo ExecuteNonQuery().
Si omette il codice, peraltro consultabile nel sorgente, in quanto identico a MySqlDirectQuery.
Gli esempi allegati chiariranno meglio i concetti.Sintassi: cl.MySqlDirectMod(String[,arraylist])Query di modifica con stringa diretta:
cl.MySqlDirectMod("Insert into Tabella1(Cognome,Data) Values('D'Azeglio','1801-10-05'")cl.MySqlDirectMod("Insert into Tabella1(Cognome,Data) Values('D'Azeglio','1801-10-05'");Query di modifica con parametri:
Dim w As New ArrayList Dim s As String = "Update Tabella1 Set Cognome=?,Data=? Where Campo3=?" Dim c As String = "D'Azeglio" Dim d As Date = CDate("05/10/1801") Dim f As Integer = 5 w.Add(c) w.Add(d) w.Add(f) cl.MySqlDirectMod(s, w)ArraList w = New ArrayList(); string s = "Update Tabella1 Set Cognome=?,Data=? Where Campo3=?"; string c = "D'Azeglio"; DateTime d = System.Convert.ToDateTime("05/10/1801"); int f = 5; w.Add(c); w.Add(d); w.Add(f); cl.MySqlDirectMod(s, w);Stored procedure
Com'è noto, le stored procedure (SP) sono funzioni precompilate nel motore del database, che eseguono una o più azioni in maniera automatica. Le SP possono o meno ricevere parametri in input, e restituire o meno gruppi di righe o parametri in output.
Per tali motivi, nella libreria sono presenti, essenzialmente, due tipi di strutture: la prima, che segue il consueto schema utilizzato per le query, seguendone la sintassi; la seconda invece espressamente deputata alle SP che restituiscono parametri.Come detto, la libreria agisce in maniera difforme dai driver ADO e ADO.NET, che usualmente vengono utilizzati per l'interfacciamento ai database.
Infatti, non vi sono strutture particolari che chiamino le SP: le SP vengono invocate come se ci si trovasse sulla riga di comando di MySql, utilizzando la normale tastiera.In definitiva, si eseguono le SP mediante il comando "CALL" seguito dal testo, con o senza parametri, della SP. L'analisi del codice sottostante e degli esempi a corredo, chiarirà i concetti espressi.
#Region "Stored procedure" '//MySqlStored - Primo costruttore - Senza parametri '//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'Si utilizza un trucco, consistente nel passare il comando come testo, allo scopo 'di eseguire quella che invece è una SP '//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Public Function MySqlStored(ByVal Testo As String) As DataTable Dim adapter As New MySqlDataAdapter Dim oTable As New DataTable If Not Flag Then Return Nothing Exit Function End If Try myCommand.CommandType = CommandType.Text 'Nota!! myCommand.CommandText = "CALL " + Testo + "();" adapter.SelectCommand = myCommand oTable.Clear() adapter.Fill(oTable) Return oTable Catch ex As MySqlException Throw Finally If Not adapter Is Nothing Then adapter.Dispose() If Not oTable Is Nothing Then oTable.Dispose() End Try End Function '//MySqlStored - Secondo costruttore - Con parametri '//''''''''''''''''''''''''''''''''''''''''''''''''' 'Si utilizza un trucco, consistente nel passare il comando come testo, allo scopo 'di eseguire quella che invece è una SP 'Inoltre, poiché non viene usato <ExecuteNonQuery>, il presente metodo può essere 'usato sia per le query di selezione che per le query di variazione dati. '//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Public Function MySqlStored(ByVal Testo As String, ByVal Dati As ArrayList) As DataTable Dim adapter As New MySqlDataAdapter Dim oTable As New DataTable Dim i As Integer = 0 Dim q As String = "" Dim qTemp As String = "" If Not Flag Then Return Nothing Exit Function End If Try If Dati(0) Is Nothing Then Return Nothing Exit Function End If For i = 0 To Dati.Count - 1 If IsDBNull(MySqlPar(Dati(i))) Then qTemp = "NULL" Else qTemp = MySqlPar(Dati(i)).ToString End If q = q + qTemp + "," Next q = Mid(q, 1, q.Length - 1) q = "CALL " + Testo + "(" + q + ");" myCommand.CommandType = CommandType.Text myCommand.CommandText = q adapter.SelectCommand = myCommand oTable.Clear() adapter.Fill(oTable) Return oTable Catch ex As MySqlException Throw Finally If Not adapter Is Nothing Then adapter.Dispose() If Not oTable Is Nothing Then oTable.Dispose() End Try End Function '// Stored procedure che ritornano parametri - 'I parametri ritornati, raccolti in un arraylist, '//sono solo di tipo stringa, per cui, nell'utilizzo, è necessaria la conversione. Public Function MySqlParametersOutput(ByVal Testo As String, _ ByVal InOutParam As ArrayList) As ArrayList Dim dr As MySqlDataReader Dim invia As String = "(" Dim ritorna As String = "" Dim i As Integer = 0 Dim j As Integer = -1 Dim sel As String = "" If Not Flag Then Return Nothing Exit Function End If Try For i = 0 To InOutParam.Count - 1 InOutParam(i) = MySqlPar(InOutParam(i)) If InOutParam(i).ToString.Length <> 0 Then invia = invia + InOutParam(i).ToString + "," Else invia = invia + "@" + i.ToString + "," sel = sel + "@" + i.ToString + "," j += 1 End If Next invia = "CALL " + Testo + Mid(invia, 1, invia.Length - 1) + ")" ritorna = "(SELECT " + Mid(sel, 1, sel.Length - 1) + ")" myCommand.CommandType = CommandType.Text myCommand.CommandText = invia dr = myCommand.ExecuteReader dr.Close() Dim q As New ArrayList myCommand.CommandText = ritorna dr = myCommand.ExecuteReader While (dr.Read()) For i = 0 To j If dr(i) Is DBNull.Value Then q.Add(DBNull.Value) Else q.Add(MySqlParamOut(dr.GetString(i))) End If Next End While dr.Close() Return q Catch ex As MySqlException Throw End Try End Function #End RegionLa prima delle funzioni riportate (MySqlStored), sovraccaricata come le query, accetta il testo della SP, ma non i parametri, essendo una SP senza parametri.
La stringa testo, preceduta dal comando "CALL", viene passata direttamente a MYSql tramite il command, che restutisce un gruppo di dati raccolti in un adapter, il quale a sua volta costruisce una datatable che viene restituita dal metodo.
Come si può notare, il meccanismo è identico in tutto e per tutto a quello utilizzato per le query.La seconda versione richiede, nella firma del metodo, i parametri in ingresso.
Ancora una volta, il meccanismo di azione è identico a quello usato nelle query, nel senso che i parametri, passati tramite un arraylist, vengono analizzati dalla funzione di servizio MySqlPar, per poi costruire la stringa da inviare al server, preceduta da un comando "CALL".
Il ritorno del metodo, se significativo (potrebbe non esserlo, se la SP non restituisce righe), viene gestito nel modo consueto.La terza versione, scritta per le SP deputate a restituire parametri, è invece completamente diversa.
Chiunque abbia avuto a che fare con la collezione parameters dei database, conosce la complessità e la prolissità dei metodi che gestiscono la detta collezione. Sorvolo, inoltre, sulla loro utilità (ma questa è un'opinione personale).
Per comprendere pienamente MySqlParametersOutput, bisogna soffermarsi su come MySql, dalla linea di comando (come sempre), agisce in tali casi.Il meccanismo è il seguente: tramite un'istruzione "CALL", acquisisce il testo e l'elenco dei parametri; immediatamente dopo, mediante un'istruzione "SELECT" seguita dall'indicatore "@", restituisce i parametri richiesti.
Lo stesso schema è stato seguito in MySqlParametersOutput:
- viene acquisita la stringa e l'arraylist che contiene i parametri input ed ouput
- MySqlPar, funzione di servizio, opera le opportune conversioni
- viene costruita la prima stringa di comando, preceduta da "CALL"
- viene costruita la seconda stringa di comando, preceduta da "SELECT @..." deputata a restituire tutti i parametri
- con due successive chiamate di un datareader, viene passata al server la richiesta (stringa "invia") e il valori di ritorno (stringa "ritorna")
- il datareader (dr) restituisce i valori in un arralist [q]
- l'arraylist [q] è il valore di ritorno del metodo.
- i parametri di ritorno sono tutti di tipo stringa, per cui sarà cura dello sviluppatore operare le opportune conversioni nel proprio applicativo.
Sintassi: ArrayList = MySqlParametersOutput(String,ArrayList)Esempio
Sp5 è una stored procedure che accetta due parametri di tipo stringa in input e restuisce due parametri, uno di tipo double e l'altro di tipo data.
La struttura è la seguente:CREATE PROCEDURE sp5 /* commento a piacere, se lo si desidera */ (IN p1 varchar(50), IN p2 varchar(50), OUT p3 double, OUT p4 date) BEGIN SELECT importo INTO p3 FROM tab1 WHERE Cognome=p1 AND Nome=p2; SELECT data INTO p4 FROM tab1 WHERE Cognome=p1 AND Nome=p2; ENDI parametri di input/output vengono trasmessi tramite l'ArrayList [w].
I parametri di output, raccolti dall'ArrayList [t], vengono aggiunti ad una ListBox:Dim w As New ArrayList Dim t As New ArrayList Dim i As Integer = 0 ReturnList.Items.Clear() w.Add("Rossi") '----->; In w.Add("Mario") '----->; In w.Add("") '---------->; Out w.Add("") '---------->; Out t = cl.MySqlParametersOutput("sp5", w) For i = 0 To 1 ReturnList.Items.Add(t(i)) NextArrayList w = new ArrayList(); ArrayList t = new ArrayList(); int i = 0; ListBox1.Items.Clear(); w.Add("Rossi"); //------> In w.Add("Mario"); //------> In w.Add(""); //-----------> Out w.Add(""); //-----------> Out t = cl.MySqlParametersOutput("sp5", w); for (i = 0; i <= 1; i++) { ListBox1.Items.Add(t[i]); }Conclusione
Qui finisce la prima parte, in cui sono stati illustrati i metodi principali della libreria MyClient, per interfacciare una applicazione con MySql.Nella seconda parte, verranno trattate le funzioni, le utility, il backup/restore e le transazioni.
Verrà inoltre fornito, oltre al codice della libreria, anche un piccolo esempio di uso, utile per iniziare a familiarizzarsi con la libreria.