Autore Topic: Tabella di DB.SQLite3 vuota  (Letto 2365 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Tabella di DB.SQLite3 vuota
« il: 22 Febbraio 2010, 00:01:21 »
Mi succede un fatto assai strano. Nel mio programma ho inserito la seguente istruzione di inserimento dati in una tabella, definita con "Primary key", composta da due colonne contigue, la prima e la seconda di ciascuna riga:
Codice: [Seleziona]
DB_Connection.EXEC("INSERT INTO Movimgg VALUES(" & Val(Colonna1_Key1) & ", '" & Colonna2_Key2 & "', '" & Colonna3 & "', '" & Colonna4 & "', '" & Colonna5 & "', '" & Colonna6 & "', '" & Colonna7 & "', '" & Colonna8 "')")
 DB_Connection.Commit
Ebbene il programma sembra eseguire l'istruzione EXEC senza dare errori e va avanti come se tutto fosse andato bene, ma in effetti non ha inserito il record. Detta istruzione è copiata da un'altra simile che svolge il lavoro di inserimento dati in una tabella diversa, in un altro passo del programma. Lì il lavoro viene svolto veramente e bene, tanto che stavo cominciando a fare amicizia con SQLite3. È da ieri che sbatto il muso su codesta istruzione e non riesco a venirne fuori. Oggi ho fatto un'altro tentativo: ho scritto un programmino semplicissimio che cerca la tabella "movimgg" se la trova la cancella e la ricrea, inserendovi dopo un solo record.
Risultato: nessun problema la tabella è validimante valorizzata col record inserito con la stessa istruzione scritta sopra.
Ritornando al problema, la connessione è aperta bene; ho guardato in debug la finestra DB_Connection ed ho visto che il DB è puntato come dovuto.
Debbo anche dire alcune istruzioni prima interrogo un'altra tabella del DB, da cui prelevo un codice che devo trascrivere nella tabella "Movimgg" per realizzare il collegamento fra le due tabelle; quella lettura si svolge con successo. Ma allora che succede?
Spero che mi possiate accendere la lampadina.
Ciao a tutti.
:ciao:

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: Tabella di DB.SQLite3 vuota
« Risposta #1 il: 22 Febbraio 2010, 11:07:26 »
Potresti postare tutta la porzione di codice interessata? Vale a dire anche quella dove, come dici, interroghi il DB per prelevare il dato che poi inserisci successivamente con l'istruzione che ha messo?
Visita il mio sito personale: http://www.leonardomiliani.com

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #2 il: 22 Febbraio 2010, 12:24:49 »
hai provato a vedere come si comporta usando il metodo hres=db_connection.edit(nometavola)

hres!nomecampo1=valore1
hres!nomecamnpon=valoren

db.connection.commit

ti ricordo che usando INSERT into devi dare un valore a tutte le colonne della tabella a meno che non specifichi prima i campi in cui vuoi inserire i valori

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #3 il: 22 Febbraio 2010, 12:38:18 »
Potresti postare tutta la porzione di codice interessata? Vale a dire anche quella dove, come dici, interroghi il DB per prelevare il dato che poi inserisci successivamente con l'istruzione che ha messo?
Sarebbe meglio, secondo me, allegare tutto il programma, comprensivo delle tabelle per una eventuale prova, ma non so come fare per allegare anche le tabelle. Intanto riporto qui sotto tutta la Sub dove si verifica l'inconveniente, preceduta dalle dichiarazioni poste in testa alla classe di appartenenza:
Citazione
Codice: [Seleziona]
' Gambas class file

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 RecTab AS Result

PUBLIC SUB MovDigOk_Click()
DIM b_nupro AS Byte
DIM f_ImpMov AS Float


DIM i_Som AS Integer
DIM i_CoVoContab AS Integer
DIM i_data AS Integer
DIM i_ImpMov AS Integer
DIM i_orario AS Integer
DIM i_RgGriMov AS Integer

DIM $_Benef AS String
DIM $_Como AS String
DIM $_Data AS String
DIM $_Descr AS String
DIM $_GG AS String
DIM $_MM AS String
DIM $_AA AS String
DIM $_orario AS String
DIM $_ora AS String
DIM $_minuti AS String
DIM $_secondi AS String
DIM $_Moneta AS String

  IF $_DescrUlt <> "" THEN
      $_TabNewDescr.Add($_DescrUlt)     'trascrive le nuove descrizioni, inserite nella giornata corrente, in attesa di ricorreggerle in caso di ripresa ddel movimento caricato nella griglia dei movimenti della giornata
      $_DescrUlt = ""         'Serve a consolidare l'aggiunta della nuova descrizione nella DescrMovDig.List
  ENDIF
  IF ImpMovDig.Text = "" THEN
     ImpMovDig.SetFocus
  ELSE
    IF DescrMovDig.Text = "" THEN
        DescrMovDig.SetFocus
    ELSE 
      IF SegnoEU.Text = "" THEN
          SegnoEU.SetFocus
        ELSE
          i_RgGriMov = 0
          DO UNTIL GriMovv[i_RgGriMov, 1].text = ""   'cerca la prima riga libera (con campo descrizione vuoto"
            INC i_RgGriMov
            IF i_RgGriMov > GriMovv.Rows.count THEN
                BREAK
            ENDIF
          LOOP
 
          SELECT CASE SegnoEU.Text
                  CASE "E", "U"     'il movimento in trattamento è un movimento di Entrata/Uscita ordinaria
                    GriMovv[i_RgGriMov, 1].text = VoContMoDig.Text
                    GriMovv[i_RgGriMov, 5].text = BenefMovG.Text
                  CASE ELSE         'il movimento in trattamento è un movimento di tipo "Prestito momentaneo"
                    GriMovv[i_RgGriMov, 1].text = CreDebMovG.text
          END SELECT
          GriMovv[i_RgGriMov, 2].text = DescrMovDig.Text
          $_Como = ModuliVari.LevEditing(ImpMovDig.Text)
          i_Posiz = InStr($_Como, ",")
          IF i_Posiz <> 0 THEN
            $_Como = Left($_Como, i_Posiz - 1) & "." & Right($_Como, 2)
          ENDIF
          f_ImpMov = CFloat($_Como)
          SELECT CASE SegnoEU.Text
                  CASE "E", "D"
                    GriMovv[i_RgGriMov, 3].text = ImpMovDig.Text
                    i_TotEntrate += i_ImpMov
                  CASE ELSE 
                    GriMovv[i_RgGriMov, 4].text = ImpMovDig.Text
                    i_TotUscite += i_ImpMov
          END SELECT
L'istruzione seguente è quella di lettura che restituisce bene il Codice-Voce da inserire nella tabella "movimgg", ancora vuota
Codice: [Seleziona]
          '---------------------------- rilevo il codice di Voce contabile dalla Tabella piancont ---------------------------------------
          i_Posiz = RInStr(VoContMoDig.Text, " » ") - 3            'ricerca l'ultima ricorrenza di " » " VoContMoDig.Text ne segnala la posizione del primo crt della sottostringa
          $_VoceConto = Right(VoContMoDig.Text, i_Posiz)
          DB_Connection.Begin
          RecTab = DB_Connection.EXEC("SELECT * FROM piancont WHERE NomeVoce  LIKE '%" & $_VoceConto & "%'")
          i_CoVoContab = RecTab!NumVoce                                 'Codice della Voce contabile nel piano dei conti
         
 :)
Codice: [Seleziona]
          i_data = Val(ModuliVari.$_DataCont)
'--------
'--------------------------------------- routinetta di conversione dell'orario corrente in hhmmss (2 crt per ciascun sottocampo
          $_ora = Hour(Now)
          IF Len($_ora) = 1 THEN $_ora = "0" & $_ora
          $_minuti = Minute(Now)
          IF Len($_minuti) = 1 THEN $_minuti = "0" & $_minuti
          $_secondi = Second(Now)
          IF Len($_secondi) = 1 THEN $_secondi = "0" & $_secondi
          $_Data = $_AA & $_MM & $_GG
          $_orario = $_ora & $_minuti & $_secondi
          i_orario = Val($_orario)                           '    ----> orario(hhmmss) IN formato numerico
          b_nupro = CByte(GriMovv[i_RgGriMov, 0].text)       'Numero progressivo del movimento nella giornata
          SELECT CASE SegnoEU.Text
                  CASE "U", "A"
                    f_ImpMov = f_ImpMov * (-1)    'trasforma in negativo l'importo se il movimento è di Uscita, di inedbitamento o diminuzione di credito
          END SELECT
          i_Totel = BenefMovG.Count
          FOR i_Som = 0 TO i_Totel - 1
            IF BenefMovG.List[i_Som] = BenefMovG.Text THEN
                $_Benef = Str(i_Som + 1)                  'Numero progressivo del record corrispondente della Tabella "Componenti Familiari"
                BREAK
            ENDIF
          NEXT
'---------------------------------------------------------------------------------------------------------------------------------------
'--------
'--------------------------------------------------------------------- istruzioni aggiunte in prova, ma poi tolte perchè la open viene ignorata ------------------------------     
          'DB_Connection.CLOSE               'chiude il DB
          'WITH DB_Connection
          '  .Name = DBname
          '  .Open    'Riapro il DB
          'END WITH
'--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------     
          $_Descr = DescrMovDig.Text
          $_Moneta = ModuliVari.$_TipoValuta
Ecco l'istruzione incriminata con la sua commit, dopo la quale, accedendo alla tabella scopro che non è stato inserito il record comandato:
Codice: [Seleziona]
          DB_Connection.EXEC("INSERT INTO movimgg VALUES(" & i_data & ", '" & i_orario & "', '" & b_nupro & "', '" & i_CoVoContab & "', '" & $_Descr & "', '" & $_Moneta & "', '" & f_ImpMov & "', '" & $_Benef & "')")
          DB_Connection.Commit   
:-[
Codice: [Seleziona]
      
          ME.ResetAreaDigMov()        'routine che svuota il contenute di tutte le caselle del Form
      ENDIF
    ENDIF
  ENDIF
END

Dovrei ancora rifinire qualche dettaglio,ma aspetto prima di concludere positivimanete la prova.
Se ritieni non sufficiente il gruppo di istruzioni riportate qui sopra, dimmi pure cosa posso fornire oltre.
Ciao. :)
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #4 il: 22 Febbraio 2010, 12:46:56 »
hai provato a vedere come si comporta usando il metodo hres=db_connection.edit(nometavola)

hres!nomecampo1=valore1
hres!nomecamnpon=valoren

db.connection.commit

ti ricordo che usando INSERT into devi dare un valore a tutte le colonne della tabella a meno che non specifichi prima i campi in cui vuoi inserire i valori
Si, cito tutte le colonne; le devo infatti valorizzare tutte coio dati preparati durante l'inserimento del movimento di pertinenza. Per maggiore chiarezza allego il programmino che ho realizzato per provare esclusivamente l'inserimento di un solo record sempre nella stessa tabella e ti posso assicurare che svolge il suo lavoro egregiamente.
:ciao:

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: Tabella di DB.SQLite3 vuota
« Risposta #5 il: 22 Febbraio 2010, 15:26:03 »
Ho notato che spesso le funzioni di gestione dei DB di Gambas sono un pò capricciose.
Hai provat a riaprire la connessione proprio prima di eseguire l'istruzione incriminata?
Visita il mio sito personale: http://www.leonardomiliani.com

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #6 il: 22 Febbraio 2010, 15:43:10 »
Ho notato che spesso le funzioni di gestione dei DB di Gambas sono un pò capricciose.
Hai provat a riaprire la connessione proprio prima di eseguire l'istruzione incriminata?
Non so se hai notato le istruzioni, riportate come commento,  subito prima dell'istruzione INSERT
Codice: [Seleziona]
'--------------------------------------------------------------------- istruzioni aggiunte in prova, ma poi tolte perchè la open viene ignorata ------------------------------     
          'DB_Connection.CLOSE               'chiude il DB
          'WITH DB_Connection
          '  .Name = DBname
          '  .Open    'Riapro il DB
          'END WITH
'--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------   
 
È una prova che ho eseguito, ma ho dovuto abbandonarle subito perchè il programma si comporta come se non eseguisse la open del DB; infatti produce il seguente errore:
Codice: [Seleziona]
Query failed: the database file is locked
:o
Ciao.

:ciao:

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #7 il: 22 Febbraio 2010, 23:14:58 »
a far le cose benfatte dovresti postare tutto il programma e il db,, nel programmino che hai postato prima ho notato che  cancelli la tabella moving, poi la ricrei e poi ci scrivi dei record il tutto con un unico commit...

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: Tabella di DB.SQLite3 vuota
« Risposta #8 il: 22 Febbraio 2010, 23:37:21 »
Riguardando il tuo codice ed alcuni miei programmi vedo che io opero in maniera differente.
Non mi affido alle query SQL lanciate con Connection.EXEC ma preferisco usare i metodi di Gambas e poi, anche a costo di sembrare ripetitivo, inserisco una ben precisa sequenza di istruzioni.

Io riscriverei il pezzo incriminato così:

Codice: [Seleziona]
DIM Connessione as NEW Connection
DIM Risultato as Result

'-- apre il DB
WITH Connessione
    .Name = NOME_DB
    .Type = "sqlite3"
    .Open
END WITH
Connessione.Begin
Risultato = Connessione.Create("mivimgg")
Risultato[CAMPO1]=DATO1
Risultato[CAMPO2]=DATO2
......
Risultato[CAMPOn]=DATOn
Risultato.Update
Connessione.Commit
Connessione.CLOSE
Visita il mio sito personale: http://www.leonardomiliani.com

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #9 il: 23 Febbraio 2010, 00:12:46 »
io lo scritto 6 post addietro 8) ma come al solito nessuno mi ascolta! ;D

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #10 il: 23 Febbraio 2010, 00:55:59 »
@fsurfing:
Prima di tutto, grazie per la tua sempre pronta disponibilità. Ho preparato gli allegati che mi hai chiesto, però ho sempre difficoltà con la connessione Internet.
Per un'eventuale prova, tieni presente:
1) il DB risiede in /ContabFam/ContabFam_DB
2) Per arrivare alla prova di inserimento record nella Tabella "Movimgg", dopo l'avvio tramite l'IDE, occorre:
     a) FMain(CoFam_Ini) »» Menù: Movimenti/Inserimento;
     b) Form1(Movimenti giornalieri) »» pulsante OK
     c) Form2(Inserimento Movimenti del: »» digitare o scegliere una voce nella ComboBox "Descrizione"
                                                                        Importo non essenziale; specificare però il Segno con "e/u"
                                                                        scegliere una voce nella ComboBox "Voce di Entrata o di Uscita"
                                                                        cliccare sul pulsante OK
Se tutto va bene il movimento digitato compare mella prima triga della gridview e vengono svuotate tutte le caselle di digitazione movimenti; viene pure registrato il movimento nella Tabella "movimgg" del DB.
Io spero che si manifesti regolarmente l'errore alla "INSERT INTO movimgg ". :D  ... così mi puoi aiutare a capire dove e come intervenire!

@Leo:
Purtroppo ho dovuto abbandonare istruzioni del tipo
Connessione.Begin
Risultato = Connessione.Create("mivimgg")
Risultato[CAMPO1]=DATO1
Risultato[CAMPO2]=DATO2
......
Risultato[CAMPOn]=DATOn
Risultato.Update

a causa dell'inserimento anomalo-automatico di una colonna ID imprevista ed indesiderata. Ho invece provato e collaudato il fedele rispetto della struttura tabellare, preparata durante il disegno del DB, delle istruzioni di tipo SQL.EXEC. Preferisco perciò proseguire sulla scelta fatta.
Ciao a tutti.
:ciao:

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: Tabella di DB.SQLite3 vuota
« Risposta #11 il: 23 Febbraio 2010, 07:27:49 »
Sì, ma se con SQL.EXEC non risolvi mentre con i metodi di Gambas sì, allora lasci perdere l'apparizione della colonna ID ma almeno risolvi il problema ("1a regola del programmatore pragmatico  ;)")
Visita il mio sito personale: http://www.leonardomiliani.com

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #12 il: 23 Febbraio 2010, 09:13:50 »
@Leo:
Supponiamo che la tua idea pratica, ma non rispondente ai miei disegni, sia da applicare, perchè l'unica presumibile funzionante, vorrei invitarti a ragionare sul comportamento strano del programma anche a livello delle seguenti istruzioni:
DB_Connection.Begin       
TRY RecTab = DB_Connection.EXEC("SELECT * FROM piancont WHERE NomeVoce  LIKE '%" & $_VoceConto & "%'")    ««   funziona benissimo
Codice: [Seleziona]
DB_Connection.CLOSE   ««  funziona benissimo
 WITH
     DB_Connection
           .Type = "sqlite3"
           .Host = FMain.DB_path
           .Login = ""
           .Password = ""
           .Name = FMain.DBname
           .Open    'Riapro il DB                ««  Non funziona ....................  pur essendo un'istruzione SQL
 END WITH

Io non riesco a spiegarmelo, perchè in altre parti del  programma utilizzo sequenze di quel tipo, cioè con Close ed Open in successione e funzionano sempre a meraviglia. Quindi se c'è un'anomalia in quel punto, la spiegazione è: commetto io un errore in quel passo di programma, oppure qualche meccanismo di Gambas non funziona.
Ti ho espresso il mio pensiero da modestissimo programmatore, inesperto di tecnicismi costruttivi di linguaggi di programmazione; spero solo che debba io aggiustare qualcosa; solo che, se è così, non ho capito ancora cosa.
Ciao
:ciao:

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: Tabella di DB.SQLite3 vuota
« Risposta #13 il: 23 Febbraio 2010, 09:55:00 »
L'errore dovrebbe essere qui:
Codice: [Seleziona]
.Host = FMain.DB_path

SQLite è un DB locale, non puoi impostargli la proprietà Host: quella è riservata a DB che girano su server quali MySQL o PostGre.
Per indicare il nome del file che contiene il DB devi usare la proprietà Name. Quindi.
Codice: [Seleziona]
.Name = FMain.DB_path

In pratica, quindi, non ti apre il DB perché non lo trova.
Visita il mio sito personale: http://www.leonardomiliani.com

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: Tabella di DB.SQLite3 vuota
« Risposta #14 il: 23 Febbraio 2010, 13:03:05 »
io ti posso consigliare una cosa, visto che il programma e già piuttosto vasto ti consigli di  non utilizzare la connessione come variabile globale ma inizializzarla in ogni funzione, questo principalmente per due motivi

1) se in qualche parte del codice in una funzione ti sei dimenticato di chiudere il db questo viene chiuso automaticamente alla chiusura della funzione

2)puoi aprire più connessioni quasi contemporane (a patto che siano tutte di lettura) per  realizzare delle funzioni di ricerca nel db tramite un modulo esterno mentre stai leggendo i valori di un altra tabella

tutti i tuoi problemi derivano dal fatto che usi PRIVATE DB_Connection AS NEW Connection  come variabile globale e da qualche parte del programma non hai correttamente chiuso il db o non effettuato correttamente il commit,oppure la connessione è gia avviata da un altra funzione del programma
Segui il mio consigli e avvia l' inizializzazione della connessione localmente alla funzione o non ne esci + fuori