Autore Topic: primi approcci con sqlite3  (Letto 4352 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #15 il: 08 Gennaio 2009, 16:49:08 »
Speravo che col nuovo anno potessi avere la gradita sorpesa di vedere funzionare nel mio primo programma Gambas la classe che ho pensato di creatre per la costruzione del DB e delle sute tabelle.  :-)

Scherzi a parte, ho cercato sia nel wiki, sia nella guida "A beginner's guide to gambas", una soluzione al mio problema che riassumo qui di seguito.

Il codice che ho scritto esegue all'avvio, nella "FMain.class" l'accesso al DB correlato per accertarne la presenza e nel caso in cui il DB non venga trovato (condizione che si può verificare ordinariamente solo alla prima esecuzione del programma), arriva il problema da risolvere, cioè il tentativo di creare una nuova classe per la formazione del DB e la costruzione della struttura tabellare necassaria a contenere i dati da immettere.

Purtroppo non riesco a capire come scrivere il codice necessario perché, nelle casistiche che sono riuscito a trovare nel Forum, non esiste un esempio calzante con la soluzione da me pensata. :cry:

Ho quindi eseguito diverse prove, ma tutte hanno prodotto esito negativo già in fase di runtime. L'ultima prova fatta é:
Citazione

All'interno della FMain.class:
Codice: [Seleziona]

PUBLIC SUB Form_Open()
  DIM DB_Connection AS NEW Connection   'inizializza la nuova connessione
  DIM DBname AS String  'Nome del Database
  DIM DB_path AS String 'Percorso di ricerca
.....................
.....................
.....................
 DB_Connection.Open    'Tento l'apertura del DB
 IF DB_Connection.Databases.Exist(DBname) THEN   'verifica l'esistenza del DB
          Message.Info("Il DB '" & DBname & "' ESISTE GIÀ - FINE PROVA")
          DB_Connection.CLOSE               'chiude il DB
          QUIT  'Esce dal programma
  ELSE
          SELECT Message.ERROR("Attenzione! ->  archivio '" & DBname & "' NON TROVATO", "Creare DB ex novo", "Uscita dal programma")
                 CASE 1
                        DIM CreDB AS NEW Class()    'creazione della classe di costruzione del Databse e delle sue Tabelle dati
                        CreDB AS ScriviDB  
                 CASE 2      
                        Message.Info("hai premuto il pulsante: Uscita dal programma - FINE PROVA")
          END SELECT
          QUIT    'Esce dal programma
  ENDIF
.....................
.....................
END

Dopo avere cliccato col tasto dx del mouse sull'iconcina "Classi >> Nuovo"
ho riportato nella ScriviDB.class il codice già testato con successo precedentemente per la creazione del DB e della costruzione della sua prima tabella.

A questo punto ho tentato l'esecuzione del propgramma, ottenendo la seguente rispostaccia:
Citazione

Unexpectecd DIM alla linea 2 in ScriviDB.class


 :-?
E' come se mancasse una definizione come prima riga della classe appena creata. Francamente non ci capisco niente. Non sto a riportare tutte le rpove fatte; sarebbe troopo lungo e fuorviante. Già il ricordo di avere quasi festeggiato il 2009 immersdo nella ricerca del "Guasto di ... classe>" mi fa venire la tremarella. :freddo:  :-)
Potreste aiutarmi a superare questo mio livello di ignoranza?
  :ciao:  :ciao:
:ciao:

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #16 il: 08 Gennaio 2009, 19:27:09 »
posta il codice della classe

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #17 il: 08 Gennaio 2009, 23:19:37 »
Citazione

fsurfing ha scritto:
posta il codice della classe


Come vuoi, ma come ho indicato nella mia precedente comunicazione ho solo sua traferito nella classe il codice relativo alla definizione del DB e della prima tabella.
Citazione

DIM sql AS String 'serve per eseguire i comandi sul DB
DIM sqltable AS Result
DIM DB_Connection AS NEW Connection  
DIM DBname AS String  'Nome del Database

Message.Info("Complimenti!!! - Sei entrato nella classe di creazione del DB e delle sue Tabelle")

DB_Connection.Databases.Add(DBname)         'crea il DB
DB_Connection.CLOSE               'chiude il DB
Message.Info("DB '" & DBname & "' Creato - Ora creo Tabella 'movimgg' ")
WITH
    DB_Connection
    .Name = DBname
    .OPEN    'Riapro il DB
END WITH
                       
sql = "CREATE TABLE 'Movimgg'  ("
sql = sql & " 'PrimChi1' CHAR(8),"        'DtMovvgg (Data-Movimento-giornaliero) é la prima parte della chiave primaria
SQL = SQL & " 'PrimChi2' INTEGER,"          
SQL = SQL & " 'PrimChi3' CHAR(8),"          
SQL = SQL & " 'Descr' VARCHAR(100) DEFAULT NULL,"
SQL = SQL & " 'TipoValuta' CHAR(1) DEFAULT NULL,"        'Valuta monetaria circolante
SQL = SQL & " 'Imp' FLOAT DEFAULT NULL,"
SQL = SQL & " 'Benef' CHAR(1) DEFAULT NULL,"
SQL = SQL & "  PRIMARY KEY ("                            'collegamento dei campi componenti la primary key
SQL = SQL & " 'PrimChi1',"                                'primo campo della primary key
SQL = SQL & " 'PrimChi2',"                             'secondo campo della primary key"
SQL = SQL & " 'PrimChi3'"                              'terzo campo della primary key    
SQL = SQL & " ));"                                        
sqltable = DB_Connection.Exec(sql)
Message.Info("Tabella 'Movimgg'  Creata - FINE PROVA ")

Grazie, Ciao.
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #18 il: 09 Gennaio 2009, 10:47:06 »
Domande:
a) Sei sicuro di aver postato tutto del file? Il testo che hai inviato dovrebbe essere incluso in un metodo di classe, oppure in una funzione di un modulo (magari la Main()).
b) La riga di errore a quale riga effettiva corrisponde?
c) Controlla se la prima riga del file (classe e modulo) abbia una nota di definizione "'Gambas ecc."; questa prima riga non và mai tolta!

Suggerimenti:
1) invece di "SQL = SQL &", scrivi "SQL &="; è lo stesso, ma più leggibile e scrivi meno... :-)
2) onde evitare situazioni appese: è giusto che tu chiuda preventivamente il db prima di riaprirlo, ma non puoi sapere se è stato veramente aperto o meno; nel qual caso potresti avere un errore che ti manda in crash il programma. Prova a inserire un "TRY db.Close()"; la TRY, in caso di errore, ti trappola l'errore e ti permette di continuare con il codice.
3) In realtà, l'array Databases dell'oggetto DB, ha senso solo nel caso di database relazionali del tipo PostgreSQL, MySQL, ecc., che gestiscono più database all'interno di ina stessa sessione; nel caso di SQLite, ha meno senso, anche perchè non credo che questo database possa supportare più db in conteporanea nello stesso file.
4) Perchè l'utilizzo della sintassi "DIM CreDB AS NEW Class()", mentre puoi utilizzare "DIM CreDB AS NEW ScriviDB"?
5) Il metodo "Exec()" può ritornarti un oggetto nullo, quindi conviene testarlo prima di utilizzarlo
6) Non è detto che il DB può essere trovato solo all'inizio del programma, e se qualcosa ti cancella il file sotto il naso? Riguardo ad un db server, questo può cadere per tantissime ragioni, per cui la cosa sarebbe meglio controllarla...
7) Il comando QUIT può essere usato per terminare bruscamente un programma, ma sarebbe buona norma non utilizzarlo; questo comando non rilascia correttamente le risorse, e può provocare una serie di anomalie a posteriori... (è un consiglio...)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #19 il: 10 Gennaio 2009, 23:41:15 »
Citazione

md9327 ha scritto:
Citazione

Domande:
a) Sei sicuro di aver postato tutto del file? Il testo che hai inviato dovrebbe essere incluso in un metodo di classe, oppure in una funzione di un modulo (magari la Main()).
b) La riga di errore a quale riga effettiva corrisponde?
c) Controlla se la prima riga del file (classe e modulo) abbia una nota di definizione "'Gambas ecc."; questa prima riga non và mai tolta!


Risposte:
a) No, per contenere l'impegno di chi mi voglia aiutare, ho riportato solo le righe interesanti nella "FMain.cla22, mentre della "ScriviDB.class" non ho ho riportato alcuna riga perché non ho aggiunto alcuna nuova istruzione .
b) la riga di riferimento dell'errore é la prima della "CreaDBContab.Class".
c) Sia la "FMain.class" che la "ScriviDB.Class" contengono la riga di commento "' Gambas class file"


Citazione

Suggerimenti:
1) invece di "SQL = SQL &", scrivi "SQL &="; è lo stesso, ma più leggibile e scrivi meno... :-)
2) onde evitare situazioni appese: è giusto che tu chiuda preventivamente il db prima di riaprirlo, ma non puoi sapere se è stato veramente aperto o meno; nel qual caso potresti avere un errore che ti manda in crash il programma. Prova a inserire un "TRY db.Close()"; la TRY, in caso di errore, ti trappola l'errore e ti permette di continuare con il codice.
3) In realtà, l'array Databases dell'oggetto DB, ha senso solo nel caso di database relazionali del tipo PostgreSQL, MySQL, ecc., che gestiscono più database all'interno di ina stessa sessione; nel caso di SQLite, ha meno senso, anche perchè non credo che questo database possa supportare più db in conteporanea nello stesso file.
4) Perchè l'utilizzo della sintassi "DIM CreDB AS NEW Class()", mentre puoi utilizzare "DIM CreDB AS NEW ScriviDB"?
5) Il metodo "Exec()" può ritornarti un oggetto nullo, quindi conviene testarlo prima di utilizzarlo
6) Non è detto che il DB può essere trovato solo all'inizio del programma, e se qualcosa ti cancella il file sotto il naso? Riguardo ad un db server, questo può cadere per tantissime ragioni, per cui la cosa sarebbe meglio controllarla...
7) Il comando QUIT può essere usato per terminare bruscamente un programma, ma sarebbe buona norma non utilizzarlo; questo comando non rilascia correttamente le risorse, e può provocare una serie di anomalie a posteriori... (è un consiglio...)


Risposta a "Suggerimenti":
Ti ringrazio per i preziosi consigli, solo che da neofita ho difficoltà a comprenderli tutti; riprendo solo quelli che ho capito meno o non ho capito per niente:
3) Se l'ho fatto non mi sono reso conto di avere costruito un array Database. :-o  E' tutta colpa del mio stato di neofita. Infatti non devo realizzare un array di detto tipo.
5) Testare il metodo "Exec()" -->  ???
6) Il progetto che vorrei realizzare girerrà solo su pc stand-alone, quindi il DB, una volta generato, non dovrebbe correre rischi di ...magia nera  :-).
7) Il comando QUIT é quello che sono riuscito a trovare poter uscire dal progetto. In V.B. utilizzavo il comando "END", ma ho provato ad utilizzarlo in Gambas e produce un errore.
 Ho capito: QUIT é insicura; allora cosa usare per uscire e chiudere l'applicazione in maniera non traumatica?


Mi sono reso conto che a questo punto della discussione sono abbastanza malconcio  :duro: , figuriamoci alla fine, ...se mai ne uscirò! :-)

In questo momento mi sento come paralizzato e non riesco a formulare più alcuna ipotesi risoluitiva, se non quella di abbandonare la creazione di una nuova classe per la definizione del DB occorrente. Però dal punto di vista della mia crescita formativa in Gambas farei un passo da gamb...ero.;-)
 :ciao:
:ciao:

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: primi approcci con sqlite3
« Risposta #20 il: 11 Gennaio 2009, 06:42:07 »
1)
scusate se mi intrometto.... ma questo codice:
Codice: [Seleziona]

CASE 1
  DIM CreDB AS NEW Class

è errato. Come riporta la documentazione di Gambas:
Citazione

All DIM declarations must be in the FUNCTION or SUB before the first executable command.

Non puoi dichiarare una variabile/oggetto/altro in mezzo alle istruzioni ed ai comandi: lo devi fare tutto in cima alla procedura/funzione, prima della prima istruzione.

Probabilmente la DIM a cui si riferisce Gambas è proprio quella.

2)
Per chiudere un programma si dovrebbe usare l'evento Close() affinché Gambas avvii la gestione della chiusura tramite la Sub Form_Close(), dove puoi mettere del codice tuo. Per invocarlo basta invocare ME.Close da un qualsiasi punto del form/class che si vuole chiudere.
Visita il mio sito personale: http://www.leonardomiliani.com

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #21 il: 11 Gennaio 2009, 23:45:05 »
Citazione

leo72 ha scritto:
 Come riporta la documentazione di Gambas:
Citazione

All DIM declarations must be in the FUNCTION or SUB before the first executable command.


Mi dispiace avere incomodato la comunità per aiutarmi a conoscere Gambas, perché mi rendo conto di avere cominciatoo ad approcciarmi con codesto linguaggio nel modo meno semplice, ma ormai ho cominciato. Ho capito ed ho anch'io avuto il dubbio, nell'usarla, che la dichiarazione della variabile nel bel mezzo del codice potesse dare fastidio; però visto che nella mia idea la classe dinamica potesse essere creata al momento del bisogno e che si creasse con una "Dim variabile as new ...", ho immaginato che potesse anadare ugualmente bene la sua dichiarazione nel corso dell'esecuzione del programma.

Non essendo così, mi sembra necessario allora fissare dei paletti importanti per capire il resto:
1)una classe dinamica non viene creata al momento della sua dichiarazione;
2)essa viene creata solo quando viene referenziata;
3)viene richiamata per l'esecuzione del codice in essa contenuto subito dopo la sua creazione, cioè sempre quando viene referenziata.
4)All'interno della classe dinamica occorre  scrivere il codice dentro una funzione o una”Private Sub” per ottenerne l'esecuzione;
5)Terminata l'esecuzione del passo di funzione o Sub utilizzato, il programma riprende a svolgeresi con l'istruzione successiva a quella di referenza della classe dinamica.
Es,:
Codice: [Seleziona]

PUBLIC SUB Form_Open() 'Nella Fmain.Class
DIM CreDB AS ScriviDB
......................................
......................................
CreDB = NEW ScriviDB 'momento di creaziione della classe dinamica e
                                dell'esecuzione del codice in essa contenuto

if Esito = si      'istruzione da cui riprende il programma dopo l'esecuzione
                    delle istruzioni contenmute nella classe riferenziata alla
                    riga prcedente
..............................
else
Message.ERROR("Attenzione! ->  operazione fallita”)
ENDIF

Ho capito?

Se non ho capito occorrerebbe una spiegazione dettagliata in merito, semprecché si possa fare all'interno di una discussione! :roll:

 :ciao:
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #22 il: 12 Gennaio 2009, 01:17:48 »
In effetti, la definizione delle variabili, segue la logica usata nei linguaggi tipo il C (non C++), che deve essere fatta all'inizio di una classe (o funzione), e mai in mezzo al codice operativo.

Riguardo ai punti di domanda:

1) la dichiarazione non è, di per sè, la creazione effettiva di una variabile (o oggetto, è lo stesso...), a meno che non venga usata la sintassi:
Codice: [Seleziona]

DIM var1 AS NEW Object[]

in questo caso, la parola NEW, oltre a dire all'interprete che tipo di variabile verrà trattata all'interno della funzione, ne viene creata pure un'istanza ovvero, verrà creata veramente, occupando un'effettiva area di memoria.

2) la referenziazione di una variabile di tipo base (es. Integer) avviene proprio durante la sua dichiarazione con DIM, e impostata ad un valore di default, dipendente dal tipo di variabile (es. Integer=0, Boolean=FALSE, ecc.); per gli oggetti il comportamento è un pò diverso, dato che questi sono componenti complessi, per cui è necessario crearli in memoria, prima di utilizzarli. Se mentre la creazione di un riferimento ad un oggetto istanziato può corrispondere ad un valore NULL (magari perchè cancellato, oppure azzerato da programma), se si prova a utilizzare una variabile oggetto, anche se dichiarata, senza averla istanziata, si avrà un errore, e il programma andrà in crash.

3) l'esecuzione del codice di oggetto non viene eseguito alla creazione dello stesso, a eccezione di alcuni metodi che, se inseriti nel codice, verranno applicati secondo la loro natura, come ad esempio il metodo "_new()". Una descrizione di questi metodi l'ho inserita nel wiki qualche tempo fà, dagli un'occhiata.

4) il concetto di PUBLIC e PRIVATE, come per STATIC, PROPERTY, e anche READ, penso di averlo descritto un pò nel wiki, per cui prima dagli un'occhiata, poi magari se hai dubbi, cercherò di dissolverli.

5) l'esecuzione del codice avviene in maniera sequenziale all'interno di una stessa funzione (o procedura), ma la logica di come vengono chiamate le funzioni, o i metodi e gli eventi di una classe, dipende dal tipo di programma che stai costruendo. Ti faccio un esempio...
In qualsiasi linguaggio, esistono due macro gruppi di classi: procedurali e di interfaccia. Il primo gruppo comprende tutte quelle metodologie e logiche, che non necessitano di un supporto o di un colloquio con l'utente; il secondo gruppo, invece , comprende tutti quegli oggetti che interagiscono con l'utente (mouse, tastiera, ecc.), oppure ad eventi particolari (es. un timer). Per quest'ultimo gruppo, quindi, sono previste funzionalità adatte all'intercettazione di questi eventi, che richiamano di norma un particolare metodo, dipendentemente dalla tipologia dell'evento stesso; è ovvio pensare che, per un click del mouse, il metodo che ne riceve la chiamata, sappia a quale posizione dello schermo è stato effettuato il click (x,y), per cui alla funzione che viene chiamata verranno passate le coordinate del click.

Per ora mi fermo qui...

Se hai dubbi, il forum è qui apposta... :-)

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: primi approcci con sqlite3
« Risposta #23 il: 12 Gennaio 2009, 12:20:07 »
Quando istanzi una nuova classe con NEW l'unica porzione di codice di quella classe che viene eseguita è quella contenuta nella sub "_new()" della classe stessa, che contiene appunto il codice che deve essere eseguito durante la sua creazione (es.: inizializzazione di variabili interne alla classe, ecc...). Il resto del codice viene eseguito solo quando viene chiamato dall'esterno, ad esempio invocando un metodo della classe stessa: MiaClasse.Funzione().
Visita il mio sito personale: http://www.leonardomiliani.com

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #24 il: 12 Gennaio 2009, 23:07:33 »
Grazie per il grande aiuto. Ho capito, almeno così credo. Ho rivisto un pò tutto come mi avete suggeritio ed ho modificato di conseguenza il mio codice, sia portando la Dim incriminata all'inizio della "FMain.class, sia costruendo una "Public Sub_new() nella nuova classe. Ho riordinato le istrruzioni inserendole opportunamente nel programma e finalmente la sua esecuzione prosegue con successo e senza errori.:1birra:

Mi resta ancora un dubbio sull'occupazione di memoria da parte della classe dinamica, una volta svolto il suo compito. Mi spiego meglio:
La classe dinamica si forma nel momento in cui viene referenziata e va ad occupare la quantità di memoria che le necessita. Dopo che le istruzioni in essa contenute ha terminato il suo lavoro. AS questo punto, per liberare la porzione  di memoria che detta classe dinamica ("ScriviDB.Class") ha impegnato, é necessario che lo faccia tramite codice oppure, una volta concluso il suo lavoro, viene automaticamente liberata anche la porzione di memoria impegnata?

Spero di essere stato chiaro.  :ciao:  :ciao:
:ciao:

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: primi approcci con sqlite3
« Risposta #25 il: 12 Gennaio 2009, 23:40:53 »
Gambas gestisce automaticamente la memoria rilasciando quella occupata da oggetti non più referenziati in maniera automatica. Quindi non devi preoccuparti di farlo tu: ci pensa l'interprete stesso a "fare pulizia".
Visita il mio sito personale: http://www.leonardomiliani.com

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #26 il: 04 Febbraio 2009, 00:06:14 »
31-gen-2009

Dopo avere creato il mio primo DB sqlite3 e le prime due tabelle, mi trovo a dovere leggere una delle tabelle per ottenere da essa la data da caricare nelle combobox Giorno, Mese, Anno. Però la prima volta che il programma va in esecuzione il DB non contiene ancora tabelle valorizzate. Dovendo riconoscere se la tabella é vuota avrei bisogno di potere interrogare la condizione “and”  di BOF, EOF. In VB potevo utilizzare l'istruzione:
Citazione

IF “Nome-DB.Nome-Tabella.BOF AND Nome-DB.Nome-Tabella.EOF THEN


In Gambas ho cercato qualche strumento simile ma non ne ho trovato (o non ne sono stato capace).
:roll:
Mi sono comportato così
Citazione

Codice: [Seleziona]

PRIVATE $DataCont AS String
PRIVATE DB_Connection AS NEW Connection  
PRIVATE DBname AS String  'Nome del Database'''
PRIVATE DB_path AS String 'Percorso di ricerca del Database ContabFam.db
PRIVATE sql AS String                  'serve per eseguire i comandi sul DB
PRIVATE NomeRec AS Result

DB_Connection
      .Type = "sqlite3"
      .Host = DB_path
      .Name = DBname
      .OPEN    'Apro il DB
      .Login = ""
      .Password = ""
  END WITH
DB_Connection.Begin
  NomeRec = DB_Connection.Edit("GGAperte")  'collega il campo di memoria NopmeTab alla Tabella GGAperte in modalità lettura record
 $DataCont = NomeRec!DtCoGGAp  'carico in memoria il contenuto dell'elemento Data-contabile della 1^ riga della tabella "GGAperte"
   IF $DataCont = "" THEN
       Message.Info("Tabella  'GGAperte' -->  V U O T A")
  ENDIF        



Però così facendo l'esecuzione di:
Codice: [Seleziona]

$DataCont = NomeRec!DtCoGGAp


Ricevo l'errore:
Citazione

Reult is not available


 :-?  
Devo trovare un'altra soluzione, ma quale? Potete aiutarmi?
 :ciao:
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #27 il: 04 Febbraio 2009, 09:40:22 »
Chiedo scusa per la precipitata formulazione della mia richiesta di soccorso, ma l'ora gtarda mi ha annebbiato la mente  e... . Poi la notte ha portato consiglio ed ho modificato il codice aggiungendo l'istruzione "TRY", ottenendo il seguente spezzone di di codice:
Citazione

Codice: [Seleziona]

TRY $DataCont = NomeRec!DtCoGGAp  
  IF ERROR THEN
      Message.Info("Errore in Tabella  'GGAperte' --> " & Error.Text & " (" & Error.Code & ")")
  ENDIF


 A questo punto, eseguendo il programma ho potuto leggere il mio messaggio:
Citazione

Errore in Tabella  'GGAperte' --> Result is not available (-1)

 :-)

Ecco, ora ho il preoblema di decifrare il codice di errore ottenuto. Dove posso trovare un elenco esplicativo dei codici di errore? Grazie ancora.

 :-)    :ciao:  :ciao:
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: primi approcci con sqlite3
« Risposta #28 il: 04 Febbraio 2009, 14:38:54 »
L'errore in questione è causato dal fatto che è stato ritornato un oggetto Result vuoto dall'esecuzione della query.

Inoltre un mio consiglio: l'uso dei comandi TRY/CATCH è meglio usarle in cui può verificarsi un errore non previsto, e non per catturare errori conosciuti, a meno di una scelta in condizioni particolari. Per ritornare al tuo esempio, il ritorno da una query può ritornare: un oggetto vuoto o nullo (il tuo caso), un errore di connessione (es. la caduta del server). In questi casi sarebbe meglio inserire dei controlli a codice (es. con un IF). E' comunque valido l'inserimento della trappola CATCH alla fine del metodo.

Riguardo le funzionalità EOF/BOF, l'oggetto Result ti offre metodi alternativi; essendo questo un oggetto molto simile ad un array, puoi testare il numero di record che contiene (sempre se non null), ed eseguire un loop di lettura, oppure usare il costrutto:
Codice: [Seleziona]

FOR EACH oResult
NEXT

che esegue lo spostamento del puntatore interno all'oggetto, in modo da ritornarti un record per ogni loop, fino al completamento di tutti gli elementi, senza provocare errori. Il controllo del metodo Result.Count ti ritorna l'esatto numero di record caricati dal database.

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: primi approcci con sqlite3
« Risposta #29 il: 04 Febbraio 2009, 23:48:23 »
Un sistema molto semplice per verificare che una tabella contenga dati e/o alcuni tipi di dati è di utilizzare la proprietà Available dell'oggetto Result, che serve proprio a verificare se il record è esistente. Il tuo test potrebbe essere riscritto così:
Codice: [Seleziona]

NomeRec = DB_Connection.Edit("GGAperte")
IF NOT NomeRec.Available THEN
  Message.Warning("Tabella vuota")
ELSE
  NopmeTab alla Tabella GGAperte in modalità lettura record
  $DataCont = NomeRec!DtCoGGAp
ENDIF
Visita il mio sito personale: http://www.leonardomiliani.com