Newsgroup: it.comp.lang.visual-basic
Titolo: Compattare db access

Ciao a tutti,
 
Sto creando un' app in VB 2005 Express Edition con la quale voglio compattare i miei database access.
 
Questo codice sembra funzionare per i file .accdb (Access 2007):
 
Dim dbEngine As New Microsoft.Office.Interop.Access.Dao.DBEngine
        Dim tmpPath As String = "C:\Air\Campioni DEK.mdb" 'Application.CommonAppDataPath & "\TempDB.accdb"
        Dim dbPath As String = "K:\TUTTI I FILES MARCO\Campioni DEK.mdb" 'Application.StartupPath & "\Notes.accdb"
 
 
        Try 'Just in case...  
 
            If IO.File.Exists(tmpPath) Then IO.File.Delete(tmpPath)
            IO.File.Move(dbPath, tmpPath)
            dbEngine.CompactDatabase(tmpPath, dbPath)
 
        Catch
 
            MsgBox(Err.Description, MsgBoxStyle.Exclamation, Err.Number & "-Unable to compact database.")
 
        End Try
 
Il problema ce l' con i file .mdb; ho provato molti codici trovati su internet ma non funzionano, nel senso che le dimensioni del db nel percorso di destinazione è sempre uguale all' originale quindi non compatta.
Uno dei codici usati è questo :
 
 
Dim DaoCompatta As dao._DBEngine
        Dim sorg, dest As String
 
        DaoCompatta = New dao.DBEngine
 
        sorg = "K:\TUTTI I FILES MARCO\Campioni DEK.mdb"
        dest = "C:\air\Campioni DEK.mdb"
 
        DaoCompatta.CompactDatabase(sorg, dest)
 
Come mai, pur trovando lo stesso codice in molti siti, non si riduce l' mdb? (con alcuni codici simili addirittura aumenta di un po'!!)
 
grazie
Marco

 Ciao a tutti,
zac
Alcune cose OVVIE...ma siccome sono ovvie può darsi che ci sfuggano(a 
me talvolta son sfuggite)....
 
1) In debug metti una stampa (un debug.print...o quel che vuoi) che ti 
MOSTRI il path COMPLETO del db che prende per compattare ed il path 
COMPLETO del db che genera...quelli sono i file da controllare!
 
2) Ovviamente per compattare....ci deve essere qualcosa da 
compattare...
e per esserci qualcosa da compattare...devi aver CANCELLATO qualche 
record e/o tabella!!! Se hai SOLO aggiunto o modificato record....che 
ti compatta? la fava?(m'è scappato abbi pazienza!)
 
3)....conseguenza di 2)...compattare NON VUOL DIRE zippare...è stato 
tradotto con compattare ma in realtà recuperà gli spazi marcati come 
cancellati nel database (e credo faccia poco altro) l'equivalente di 
VACUUM di altri Database!!!
 
-- 
----- Italliaaaaa 3227! -----
Io sono Attila:
A come atrocità,
doppia T come terremoto e tragedia,
I come ira di dio,
L come laco ti sangue
e A come adesso vengo e ti sfascio le corna!
(Diego Abatantuono "Attila Flagello di Dio")
 
 

Non ho ben capito dove inserire il debug.print ma ci provo...
per il resto, se apro il front end del db e lo compatto, i KB diminuiscono quindi (teoricamente) dovrebbero diminuire anche se eseguo il comando da VB.
Ho provato su più database, quindi la possibilità che siano avvenute le modifiche di cui parli è prossima al 100% invece non vedo nulla..
per sicurezza (le cose ovvie sfuggono e hai ragione) apro un db, creo e cancello maschere e query così lo obbligo ad avere qualcosa da compattare poi provo, secondo me è il metodo migliore.
Grazie per la risposta, buona serata
 
 

> Ovviamente per compattare....ci deve essere qualcosa da 
compattare... 
 
questo mi ha suggerito di lavorare sul db con maschere e query per aumentare la dimensione e sembra funzionare tutto..
lo proverò per un po' di tempo sperando che sia tutto ok
grazie ancora
ciao

Il caro Marco75 in un impeto grammaticale scriveva:

Ovviamente non ci siamo ancora........hai parzialmente capito!
 
ACCESS è un db un po particolare...al suo interno ha anche 
l'interfaccia...quindi maschere e report!
Fai una maschera salvi il db e poi la cancelli....che succede ai dati 
di quella interfaccia grafica? BOH! probabilmente non cancella subito 
lo spazio occupato! E compattare il database ti funziona!
 
MA NON E' QUESTO QUELLO CHE FA UN DB "normale"
 
ed allora
 
Teoria "Terra Terra" di un db generico by Wodka40
 
Qualsiasi Database memorizza prima o poi struttre dati chiamate 
record...le organizza in strutture più grosse chiamate tabelle.
Il record all'interno della tabella ha un identificativo che lo rende 
individuabile univocamente.
Perchè ce l'ha? Perchè il "record" occupa spazio!
Quanto spazio occupa? Lo sa PRECISAMENTE il motore del database e lo sà 
all'INCIRCA il programmatore che ha definito la STRUTTURA del database 
definendo CAMPI con dimensioni automatiche(spesso derivanti dal tipo di 
campo) o d alui impostate (ad esempio campo INDIRIZZO 50 caratteri)
 
Comunque vada il motore del database sà:
1) Individuare un record dall'altro (ogni record ha un identificatore 
UNIVOCO...anche se non lo mostra all'utente o al programmatore)
2) Quanto spazio occupano i records!
 
Combinando queste info....una tabella di un db teorica è fatta così
 
posizione 0 ->99 Record 1
posizione 100 ->199 Record 2
....
Posizione 700->799 Record 7
...
posizione 1000 ->1199 Record 10
e via andare
 
Un indice è un modo veloce per accedere ai record....ad esempio se io 
volessi un indice ordinato per Ragione sociale popotrei costruirmi un 
file con dentro
ORDINATO PER RAGSOC.TXT
700
1000
0
100
dentro ho memorizzato i puntatori all'inizio del record che rispetta 
l'ordinamento per ragione sociale
 
BENE O CANCELLIAMO ADESSO
della struttura di sopra cancella il record 7....considera che 
spessisimo (praticamente sempre con i db standard) la tabella è UN FILE 
(o più di uno se distribuito su più cluster)....in access la tabella è 
annegata dentro un unico file con estensione MDB...
 
LO CANCELLIAMO IL RECORD 7???
bene lo cancelliamo....ma ci rimane un buco...allora dovremmo scalare 
TUTTA la struttura dei record che seguono e RIAGGIORNARE tutti gli 
indici....PERCHE? Perchè il puntatore alla zona del record 7 non c'è 
più!
QUESTA COSA è costosissima in termini di tempo e DEGRADA tantissimo le 
prestazione di un database!
COME SI RISOLVE?
con una bandierina!
Semplicemente si marchia quella zona come CANCELLATA...e si lascia nel 
file!!!
posizione 0 ->99 Record 1
posizione 100 ->199 Record 2
....
Posizione 700->799 MARCATO COME CANCELLATO!!!!
...
posizione 1000 ->1199 Record 10
 
Dove si marchia? Come si marchia?
Dipende dall'implementazione del motore db...c'è chi cancella il 
puntatore dagli indici...chi ha un indice dei cancellati...chi un 
flag...MA NESSUN DB CANCELLA SUBITO lo spazio occupato e riaggiorna gli 
indici per recuperare lo spazio!
 
MA ciò è oneroso....dopo un mese che memorizzi e cancelli il tuo file 
di tabella ha un sacco di zone inutilizzate marchiate come cancellate!
 
Ed allora?
Allora tutti i database hanno una utility che RECUPERA le "zone morte" 
del file e ricostruisce gli indici!
In alcuni DB è un tools da lanciare a parte...in altri un comando SQL 
(VACUUM per Postgresql, OPTIMIZE (ad esempio) per mysql,SHRINKDATABASE 
sqlserver....e via andare...ad es. VACUUM anche per sqlite...)
 
 
ACCESS????
Access c'ha una utility a parte che ricostruisce un ALTRO database 
compattato...ecco perchè va lanciata da GUI come accesso 
esclusivo.Dov'è l'utility? Dentro JET che sarebbe il motore database di 
Access....quello che comandi va VB...nello specifico il COMPACT non è 
nemmeno in JET ma in JRO....e se non ce l'hai installato ...non 
compatti un piffero!
http://support.microsoft.com/kb/230501/it
 
 
Morale della favola?
Access è COMODISSIMO per fare demo e mettere in piedi una 
dimostrazione...per piccolissime applicazioni con un grado di sicurezza 
richiesto minimo e dipendente in larga misura dal cliente: è un file! S 
e lo sputtana o lo perde....son cavoli amari!
 
Quindi sotto con le compattazioni...e già che ci sei...usa la 
compattazione per copiare il file compattato in un altra zona 
dell'hard-disk rinominandolo "BacukpDatidel[data].bkp"....prima o poi 
te e i tuoi clienti mi ringrazierete!
 
-- 
----- Italliaaaaa 3227! -----
Mi disturba la morte, è vero. Credo che sia un errore del padreterno. 
Non mi ritengo per niente indispensabile,
ma immaginare il mondo senza di me: che farete da soli?
(Vittorio Alfieri)