[Parte 1Parte 2Parte 3Parte 4Parte 5]


Accesso ai dati in VB
Di:Enrico Granata



Stavolta approfondiremo l'oggetto Container e Document

MyDb.Containers("Databases").UserName="MeMedesimo"

MyDb.Containers("Databases").Permissions=dbSecReadSec 'Leggi le impostazioni di sicurezza

Con questo codice l'utente MeMedesimo avrà il permesso di leggere le impostazioni di sicurezza, ma non di modificarle

Se poi vogliamo invece attribuire allo stesso MeMedesimo permessi di lettura di una tabella di nome MyTable

MyDb.Containsers("Tables").Documents("MyTables").UserName="MeMedesimo"

MyDb.Containsers("Tables").Documents("MyTables").Permissions=dbSecRetreiveData

L'organizzazione di sicurezza è divisa in Containers e Documents, ove Containers(stringa1).Documents(stringa2) identifica l'oggetto di nome stringa2 del Container stringa1

Praticamente questo è tutto ciò che c'è da dire sulla sicurezza di Jet, sembra difficile, ma consultando la guida di VB che è un riferimento completo all'argomento e che contiene anche tutte le costanti dbSec sarà più facile

Ricordate che qualche mese fa non sapevate neanche cosa fosse un oggetto Database e oggi siete arrivati alla loro sicurezza in ambienti multiutente

Passiamo quindi ad un altro argomento importante, ma meno noto, le Query con Parametri

Query variabili

Queste sono query particolari in cui alcuni valori non sono noti a priori, ma lo saranno in un secondo tempo, ad esempio in un ipotetico programma per gestire un database di una Città si potrebbe voler rimuovere tutti i record dove AnnoMorte è < 1990, ma il programma dispone solo della funzione "Rimuovi record per Anno di Morte", cioè della routine RemoveForDeathYear()

Public Sub RemoveForDeathYear()

End Sub

Voi potreste dire che non c'è bisogno delle query con parametri, basta usare l'operatore & come nel seguente esempio

Dim DeathYear As String

DeathYear=InputBox("Anno di morte")

Dim SQLQuery As String

SQLQuery="DELETE FROM Anagrafe WHERE AnnoMorte<" & DeathYear

Ma perchè fare così quando esiste una query che fa esattamente la stessa cosa?

PARAMETERS DeathYear Text; DELETE FROM Anagrafe WHERE AnnoMorte<DeathYear

L'unica cosa che questa query ha di insolito è la sezione prima del ; cioè "PARAMETERS DeathYear Text" che non fa altro che definire un parametro DeathYear che poi verrà modificato in fase di esecuzione

Prima di definire RemoveForDeathYear() dobbiamo però definire la CreateSQLQueryDefs() che nel nostro caso creerà la query con parametri

Public Sub CreateSQLQueryDefs()

Dim Query As QueryDef

Set Query=MyDb.CreateQueryDef("RemoveDeath", "PARAMETERS DeathYear Text; DELETE FROM Anagrafe WHERE AnnoMorte<DeathYear")

End Sub

Tutto è pronto per la RemoveForDeathYear() la quale grazie ai QueryDef sarà molto ristretta

Diciamo che possiamo usare in questo caso QueryDef.ExecuteSQL per ottenere il numero di righe eliminate

Public Sub RemoveForDeathYear()

Dim DeathYear As String

DeathYear=InputBox("Anno di morte")

Dim SQLQuery As QueryDef

Set SQLQuery=MyDb.QueryDefs("RemoveDeath")

SQLQuery.Parameters("DeathYear")=DeathYear

Dim NLines As Long

NLines=SQLQuery.ExecuteSQL

MsgBox NLines & " linee influenzate dall'esecuzione della Query", 64, "Informazione"

End Sub

La routine non fa altro che completare la QueryDef RemoveDeath e poi esegue con ExecuteSQL che come dicemmo nei mesi passati ritorna un Long che corrisponde al numero di Linee sulle quali la Query ha operato

Alla fine mostriamo in una MsgBox il Long ritornato e anche l'argomento

A questo punto le nostre conoscenze di Jet sono molto vaste, ci manca solo una cosa, cioè una verifica delle nostre conoscenze di Jet che potremo eseguire nello spazio rimasto in questo articolo e nel successivo, cioè creare un file di utilità generale per gestire un Database, esso non sarà un .cls, ma un .bas, così da poterlo utilizzare con Database diversi senza problemi di istanze

Rem dbMan.bas

Rem Gestore di Jet Engine

'Questa Function crea un Database

Public Function CreateDB(WorkSpace As WorkSpace,Name As String) As Database

Set CreateDB=WorkSpace.CreateDatabase(Name, dbLangGeneral)

End Function

Questa Function ritorna un oggetto Database corrispondente ad un Database creato con locale settato a dbLangGeneral nel WorkSpace e con il nome da noi voluto

La seconda Function invece apre un Database

'Questa Function apre un Database

Public Function OpenDB(WorkSpace As WorkSpace,Name As String) As Database

Set OpenDB=WorkSpace.OpenDatabase(Name)

End Function

Diciamo che queste funzioni sono molto semplicistiche, poichè omettono molti parametri nella dichiarazione, ma come esempio di uso di Jet bastano e nel caso vi serva un codice più approfondito potete sempre crearlo, in fondo siamo arrivati alla fine della serie, o no?

'Questa Function instanzia un TableDef

Public Function CreateNewTableDef(Database As Database, Name As String) As TableDef

Set CreateNewTableDef=Database.CreateTableDef(Name)

End Function

E' ovvio che la routine di creazione dei record la prenderemo dalla 2░ lezione, dove ne implementammo una versione

Public Sub AggiungiCampo(Tabella As TableDef, Nome _

As String, TipoDati As Integer, Optional Dimensione)

Dim MyField As Field

If IsMissing(Dimensione) Then

Set MyField=Tabella.CreateField(Nome, TipoDati)

Else

Set MyField=Tabella.CreateField(Nome, TipoDati, Dimensione)

End If

Tabella.Fields.Append MyField

End Sub

Questa è una prima parte della nostra dbMan.Bas che dovrebbe facilitarci la vita nell'uso di Jet

Ovviamente le routine come AppendTableDef() non vengono implementate qui poichè sono troppo facili, ma per aiutarvi ne implemento una, proprio la AppendTableDef()

'Questa Sub esegue l'Append su un TableDef

Public Sub AppendTableDef(Database As Database, Table As TableDef)

Database.TableDefs.Append Table

End Function

Praticamente queste sono le basi, per creare un QueryDef esiste una routine ancora più facile da implementare, che però fornirò io poichè questo fa parte del lavoro di scrittura di questa serie di articoli

'Questa Function ritorna un QueryDef valido

Public Function CreateNewQueryDef(Database As Database,Name As String, SQL As String) As QueryDef

Set CreateNewQueryDef=Database.CreateQueryDef(Name, SQL)

End Function

Per eseguire una query che non ritorna valori ci vorranno invece 2 routine, una per Execute e una per ExecuteSQL

Se ricordate la differenza Execute non ritorna nulla, ExecuteSQL il numero di righe interessate dalla query

'Gestione delle Query che non ritornano Recordset

Public Sub ExecuteQuery(Database As Database, SQL As String)

Database.Execute SQL

End Sub

Public Function ExecuteSQLQuery(Database As Database, SQL As String) As Long

ExecuteSQLQuery=Database.ExecuteSQL SQL

End Function

Anche su queste 2 funzioni c'è poco da dire, una è una Sub che usa Execute, un' altra è una Function che usa ExecuteSQL, per costruire i nomi è stato usato il nome del metodo seguito da Query

Esiste poi la gestione dei RecordSet che implementeremo in queste funzioni

Public Function OpenTable(Database As Database, Name As String) As RecordSet

Set OpenTable=Database.OpenRecordSet(Name)

End Function

Public Sub MoveToFirstRecord(RecordSet As Recordset)

RecordSet.MoveFirst

End Sub

Public Sub MoveToLastRecord(RecordSet As Recordset)

RecordSet.MoveLast

End Sub

Public Sub MoveToNextRecord(RecordSet As Recordset)

If Not RecordSet.Eof Then RecordSet.MoveNext

End Sub

Public Sub MoveToPreviousRecord(RecordSet As Recordset)

RecordSet.MovePrevious

End Sub

Questo è però solo l'inizio della gestione dei RecordSet che però lascio a voi in quanto nell'ultimo articolo ripasseremo tutto ciò che abbiamo imparato

Tanto per iniziare vi ricordo di implementare tutti i metodi Find e il metodo Clone(), oltre al metodo Close()

Poi ricordate CompactDatabase() e RepairDatabase() che possono sempre tornare utili, ah...infine MakeReplica() che potete usare dopo CompactDatabase(), anche se in quel contesto io preferisco Kill() e FileCopy()

Dovete poi ricordare di fornire una piattaforma stabile per dbMan, quindi cercate tutti gli errori di accesso ai dati nella guida di VB e verificate in quali casi dovreste inserirli nella Errors-Catching routine

Se siete ambiziosi ricordate che un DBMS si può realizzare in VB, certo, Access sarà sempre Access, ma un programma come VisData è già un valido DBMS di dimensioni ridotte, nonostante il numero di file che lo compongono, cose da includere in un DBMS sono praticamente tutte quelle che abbiamo studiato