Autore Topic: [Risolto] SQlite - Trattamento/Indirizzamento errato campi di tabella  (Letto 3472 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Oggi, durante l'esecuzione di un programma di test sul DB costruito dal mo programma "ContabFam" ho incontrato un'anomalia che definirei inverosimile, e cioè:
vado a leggere il contenuto di certi dati riepilogativi presenti in campi di colonne contigue della tabella di DB riepmovg
Ebbene pur avendoli richiamati correttamente, l'output fornito dalla query sql è uguale per tutti e due i campi, proprio come se contenessero entrambi lo stesso valore.
Riporto la print eseguita durante il debug del programma, per tutte le colonne di una riga della tabella incriminata:
Citazione
RecRiepMovg!IdRiepMovg= '6159'  
RecRiepMovg!DtCoMovg= '20130102'
RecRiepMovg!StaDtMovg='C'
RecRiepMovg!TotEntrg= '3110'    RecRiepMovg!TotUscg= '3110'
RecRiepMovg!RipFing= '360,52'

Come risulta chiaramente la  4^ riga di print richiama le colonne TotEntrg e TotUscg: RecRiepMovg!TotEntrg= '3110'    RecRiepMovg!TotUscg= '3110'

L'istruzione di query che precede la suddetta print é:
Codice: gambas [Seleziona]
 RecRiepMovg = ApriDB.DB_Connection.Exec("SELECT * FROM  riepmovg WHERE  DtCoMovg = '" & iGiornata & "'")
    If Not RecRiepMovg.Available
      EdtData = New EditData(iGiornata)
      Message.Error("<CENTER> ATTENZIONE !!!<BR><b> Il RECORD RIEPILOGATIVO della giornata contabile '" & EdtData.$DataEdt & "' inesistente in DB.ContabFam.riepmovg <BR><BR>IL PROGRAMMA VERRÀ CHIUSO </b></CENTER>")
      Quit
    Endif
    Print "RecRiepMovg!IdRiepMovg= '"; RecRiepMovg!IdRiepMovg; "'", "RecRiepMovg!DtCoMovg= '"; RecRiepMovg!DtCoMovg; "'", "RecRiepMovg!StaDtMovg='"; RecRiepMovg!StaDtMovg; "'", "RecRiepMovg!TotEntrg= '"; RecRiepMovg!TotEntrg; "'", "RecRiepMovg!TotUscg= '"; RecRiepMovg!TotUscg; "'", "RecRiepMovg!RipFing= '"; RecRiepMovg!RipFing; "'"
    If RecRiepMovg!TotEntrg = fTotEntr And RecRiepMovg!TotUscg = fTotUsc And RecRiepMovg!StaDtMovg = "C" Then
        iEsito = 0
    Else
      iEsito = 1
    Endif

La  vista della tabella fornita da Sqlite ed allegata qui mostra chiaramente che i nomi delle colonne sono riportati correttamente e che il contenuto delle celle nella riga di cui ho detto sopra è diverso:  
3110 per TotEntrg
3012.9 per TotUscg

Inoltre la tabella presenta altre celle delle stesse colonne con valori uguali, diversamente dalla realtà. Mi viene difficile da crederlo, ma sembra che ci possa essere qualche cattivo comportamento di software che legge e/o registra i dati in codesta tabella. Ma perché solo in essa?
Ho guardato le istruzioni di creazione della tabella ed a me sembrano corrette:
Codice: gambas [Seleziona]

Public Sub CreaRiepMovg($_NomeTab As String)        'Routine di crea'PRIVATE DB_path AS String 'Percorso di ricerca del Database ContabFam.db
'----------------------------------------------------------- CREAZIONE DELLA "Tabella di RIEPILOGO DEI MOVIMENTI GIORNALIERI" -------                      
  ApriDB = New OpenDB
  sql = "CREATE TABLE '" & $_NomeTab & "'"                  '*** Contiene i Conti e sottoconti di dettaglio utilizzabili nella procedura ***"
  sql = sql & "('IdRiepMovg' INTEGER PRIMARY KEY AUTOINCREMENT," 'codice id obbligato dalla struttura di SQLite3, ma inutile per questo DB
  sql = sql & " 'DtCoMovg' INTEGER,"  '----»» costituisce la chiave primaria d'ordinamento effettiva  e rappresenta la Data contabile della giornata di riferimento
  sql = sql & " 'StaDtMovg' CHAR(1) DEFAULT NULL,"        ' "A" = Giornata aperta, "C" = Giornata chiusa
  sql = sql & " 'TotEntrg' INTEGER,"                      'Totale Entrate di giornata
  sql = sql & " 'TotUscg' INTEGER,"                       'Totale Uscite di giornata
  sql = sql & " 'RipFing' FLOAT"                       'Saldo di fine giornata, a riportare
  sql = sql & " );"
  Try ApriDB.DBConnection.Exec(sql)
  If ApriDB.DBConnection.Error Then
      Message.ERROR("Attenzione! ->  Creazione Tabella 'ContabFamdb.RiepMovg' --> FALLITA" & Chr(10) & Chr(10) & "Cod.Erro= " & Error.Code & "»»" & ERROR.Text & Chr(10) & Chr(10) & "Il programma verrà chiuso")
      Quit
  Else
    ApriDB.DBConnection.Close               'chiude il DB
  Endif
End


 :rolleyes:
« Ultima modifica: 13 Marzo 2015, 11:35:44 da Picavbg »
:ciao:

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #1 il: 10 Marzo 2015, 22:49:06 »
Codice: gambas [Seleziona]

...
  sql = sql & "('IdRiepMovg' INTEGER PRIMARY KEY AUTOINCREMENT," 'codice id obbligato dalla struttura di SQLite3, ma inutile per questo DB
...
 


Probabilmente sto dicendo una scemenza ma sembra mancare lo spazio davanti e dietro la parentesi tonda...forse.
 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #2 il: 10 Marzo 2015, 23:04:18 »
Codice: gambas [Seleziona]

...
  sql = sql & "('IdRiepMovg' INTEGER PRIMARY KEY AUTOINCREMENT," 'codice id obbligato dalla struttura di SQLite3, ma inutile per questo DB
...
 


Probabilmente sto dicendo una scemenza ma sembra mancare lo spazio davanti e dietro la parentesi tonda...forse.
 :ciao:
No, purtroppo non è quello il problema, perché tutte le tabelle del DB sono create con la stessa tecnica di scrittura e nelle altre l'anomalia non si verifica.

Probabilmente dovrei sottoporre il problema direttamente a SQlite!, oppure ... non lo so.

L'anomalia si protrae senza che me ne sia mai accorto da troppo tempo; infatti sono diversi i record di detta tabella che nel tempo hanno determinato, forse per aggiornamenti successivi a passaggi del contenuto delle celle incriminate in campi di memoria che poi sono stati presi dal programma per riscrivere i record coi contenuti dei campi di memoria, alterati proprio in fase di lettura.
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #3 il: 11 Marzo 2015, 10:28:57 »
Stamattina ho provato a leggere la tabella e estrane il contenuto con la seguente istruzione di print:
Codice: [Seleziona]
 Print "RecRiepMovg!IdRiepMovg= '"; RecRiepMovg[0]; "'", "RecRiepMovg!DtCoMovg= '"; RecRiepMovg[1]; "'", "RecRiepMovg!StaDtMovg='"; RecRiepMovg[2]; "'", "RecRiepMovg!TotEntrg= '"; RecRiepMovg[3]; "'", "RecRiepMovg!TotUscg= '"; RecRiepMovg[4]; "'", "RecRiepMovg!RipFing= '"; RecRiepMovg[5]; "'"
Ed ecco il risultato:
Citazione
RecRiepMovg!IdRiepMovg= '6159'  RecRiepMovg!DtCoMovg= '20130102'        RecRiepMovg!StaDtMovg='C'       RecRiepMovg!TotEntrg= '3110'    RecRiepMovg!TotUscg= '3110'     RecRiepMovg!RipFing= '360,52'

Come si può notare ho trattato la variabile Result "RecRiepMovg" come se fosse un array, ma il risultato non è cambiato:  in RecRiepMovg[4] ho trovato lo stesso valore di RecRiepMovg[3].
Ora, dato che,utilizzando Sqliteman (in fedora) le colonne mostrate dal software riportano i valori corretti, debbo supporre che sia proprio Gambas a leggere il valore della cella precedente a quella corretta.
Visto però che ciò succede solamente per una tabella e solo per le due colonne incriminate, devo pensare ad una cattiva indicizzazione dei campi interni alla tabella, ma causata da che cosa?
 ???
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #4 il: 11 Marzo 2015, 14:24:15 »
Ulteriore prova:
 
Citazione
Codice: gambas [Seleziona]
RecRiepMovg = ApriDB.DB_Connection.Exec("SELECT  TotUscg, IdRiepMovg  FROM  riepmovg WHERE  IdRiepMovg = '" & 6159 & "'")
 Print "RecRiepMovg!TotUscg= '"; RecRiepMovg!TotUscg; "'"
 Print "RecRiepMovg!IdRiepMovg= '"; RecRiepMovg!IdRiepMovg; "'"

Risultato:
Citazione
RecRiepMovg!TotUscg= '0'
RecRiepMovg!IdRiepMovg= '6159'
--------------------------------------------------------------------------
Citazione
Codice: gambas [Seleziona]
RecRiepMovg = ApriDB.DB_Connection.Exec("SELECT  IdRiepMovg, TotUscg  FROM  riepmovg WHERE  IdRiepMovg = '" & 6159 & "'")
Print "RecRiepMovg!TotUscg= '"; RecRiepMovg!TotUscg; "'"
Print "RecRiepMovg!IdRiepMovg= '"; RecRiepMovg!IdRiepMovg; "'"

Risultato:
Citazione
RecRiepMovg!TotUscg= '6159'
RecRiepMovg!IdRiepMovg= '6159'
In pratica se il nome-colonna TotUscg è scritto per primo nella riga SQL SELECT il valore che viene estratto é 0 (zero), altrimenti assume il valore della colonna precedente.
Ma che senso ha?
 :o
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #5 il: 12 Marzo 2015, 16:52:10 »
Stamattina mi sono accorto di un errore presente nel comando SQL di creazione della tabella; l'errore consiste nell'avere definito le due colonne TotEntrg  e TotUscg con Type INTEGER, mentre il loro contenuto pò essere facilmente formato da valori numerici decimali. Ho allora riprovato a riorganizzare la tabella ridefinendone i type delle colonne che la compongono:
Codice: gambas [Seleziona]

  sql = "CREATE TABLE '" & $NomeTab & "'"             
  sql = sql & "('IdRiepMovg' INTEGER PRIMARY KEY AUTOINCREMENT,"
  sql = sql & " 'DtCoMovg' INTEGER," 
  sql = sql & " 'StaDtMovg' CHAR(1) DEFAULT NULL,"     
  sql = sql & " 'TotEntrg' FLOAT,"                     
  sql = sql & " 'TotUscg' FLOAT,"                     
  sql = sql & " 'RipFing' FLOAT"                       
  sql = sql & " );"
  Try ApriDB.DBConnection.Exec(sql)


Pensavo di avere finalmente capito la causa dell'anomalia riscontrata, invece, quando ho riprovato ad estrarre il suo contenuto, l'anomalia è ricomparsa in tutta la sua prepotente pienezzza.
Non so veramente più cosa tentare per risolvere questo assurdo Bug.
 :o ??? :rolleyes:
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #6 il: 12 Marzo 2015, 18:07:53 »
Volendo tagliare la testa al toro, ho dato corso ad una prova, ultima delle scarse risorse della mia fantasia: ho creato la tabella incriminata definendo tutte le sue colonne, ad eccezione della primary key, col type VARCHAR ed ho ripercorso la strada degli esperimenti pratici di questi giorni.
Codice: gambas [Seleziona]

  sql = "CREATE TABLE '" & $NomeTab & "'"   
  sql = sql & "('IdRiepMovg' INTEGER PRIMARY KEY AUTOINCREMENT,"
  sql = sql & " 'DtCoMovg' VARCHAR(8) DEFAULT NULL," 
  sql = sql & " 'StaDtMovg' CHAR(1) DEFAULT NULL,"       
  sql = sql & " 'TotEntrg' VARCHAR(10) DEFAULT NULL,"   
  sql = sql & " 'TotUscg' VARCHAR(10) DEFAULT NULL,"   
  sql = sql & " 'RipFing' VARCHAR(10) DEFAULT NULL"     
  sql = sql & " );"


Ebbene,  la prova si è conclusa bene e, finalmente, l'estrazione dei valori dalla tabella ha fornito i contenuti corretti:
Citazione
Codice: [Seleziona]
    RecRiepMovg = ApriDB.DB_Connection.Exec("SELECT * FROM  riepmovg WHERE  IdRiepMovg = '" & 6253 & "'")
    If Not RecRiepMovg.Available
       EdtData = New EditData(iGiornata)
       Message.Error("<CENTER> ATTENZIONE !!!<BR><b> Il RECORD RIEPILOGATIVO della giornata contabile '" & EdtData.$DataEdt & "' inesistente in DB.ContabFam.riepmovg <BR><BR>IL PROGRAMMA VERRÀ CHIUSO </b></CENTER>")
       Quit
    Endif
    Print "RecRiepMovg!IdRiepMovg= '"; RecRiepMovg!IdRiepMovg; "'"
    Print "RecRiepMovg!TotEntrg= '"; RecRiepMovg!TotEntrg; "'"
    Print "RecRiepMovg!TotUscg= '"; RecRiepMovg!TotUscg; "'"
Citazione
RecRiepMovg!IdRiepMovg= '6253'
RecRiepMovg!TotEntrg= '3110'
RecRiepMovg!TotUscg= '3012,90'

Secondo me, però, il BUG c'è sempre ed andrebbe affrontato ed eliminato.
Ritengo pertanto di non potere considerare risolta la presente discussione che, a parte la cortese partecipazione di Gianluigi, si é dimostrata un vero e proprio monologo.
Spero che la mia esperienza possa servire a chi dovrebbe affidare i propri dati alla struttura SQLite. Non potendone fare a meno, conviene definire le colonne delle varie tabelle occorrenti, sempre come stringhe di caratteri.

Io non ho ancora finito, infatti, proprio per l'anomalia che si è manifestata a mia completa inconsapevolezza, dovrò andare a ricalcolare tutti i valori delle celle di tabella che si sono alterati nel tempo e dovrò anche riconsiderare tutti i passi di programma dove vengono estratti e trattati i valori delle colonne oggetto della presente indagine.
 :ciao: :ciao:
:ciao:

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #7 il: 12 Marzo 2015, 21:28:47 »
Io avevo provato il tuo codice in un semplice database con una tabella simile alla tua popolata per l'occasione, perché ho notato che nella query avevi messo l'integer fra gli apici come se fosse una stringa e non avevi chiuso la query con il “;”.
Ma SQLite permette tutto e mi ritorna i dati corretti in tutti i modi.
Altre idee non me ne sono venute, però fossi in te proverei ad evitare gli apici per i numeri e chiuderei con il punto e virgola, caso mai ogni tanto SQLite si arrabbi.  :-\

 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #8 il: 12 Marzo 2015, 23:05:23 »
Scusa, ma sono distratto da un problema con la comprensione delle array di strutture e non mi ero accorto che avevi aggiunto il post dei VARCHAR.
Non credo che questa possa essere una soluzione.
Ti posto la mia prova con i numeri che funziona bene. Se non hai fatto qualche errore di algoritmo generale è impossibile che non ti funzioni. Deve esserci da qualche parte nel codice un qualcosa che cambia le carte in tavola...
Vedi se ti può essere utile anche se ne dubito...
 :ciao:
P.S. Solo ora mi accorgo di essermi dimenticato un $Conn.Close nella routine di interrogazione mi scuso.
Ho provveduto ad aggiornare il file allegato.
« Ultima modifica: 13 Marzo 2015, 00:07:09 da Gianluigi »
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQlite - Trattamento/Indirizzamento errato campi di tabella
« Risposta #9 il: 13 Marzo 2015, 11:35:13 »
Io avevo provato il tuo codice in un semplice database con una tabella simile alla tua popolata per l'occasione, perché ho notato che nella query avevi messo l'integer fra gli apici come se fosse una stringa e non avevi chiuso la query con il “;”.
:o
Ho sempre scritto i record di DB con la stessa tecnica degli apici posti a racchiudere il nome di ciascuna colonna, a parte la prima, secondo una guida letta all'inizio del mio approccio con SQLite, senza badare come fossero definiti i type delle colonne nelle rispettive tabelle di DB. Non mi ero accortio che l'esempio della guida riportava dopo la colonna ID(INTEGER) tutte colonne con type stringa.
Ora che mi hai fatto notare l'imperfezione ho rivisto i miei vecchi appunti ed ho corretto sia il CREATE che l'INSERT INTO nel programma:
Citazione
Codice: gambas [Seleziona]

  sql = "CREATE TABLE '" & $NomeTab & "'"
  sql = sql & "('IdRiepMovg' INTEGER PRIMARY KEY AUTOINCREMENT,"
  sql = sql & " 'DtCoMovg' INTEGER," 
  sql = sql & " 'StaDtMovg' CHAR(1) DEFAULT NULL," 
  sql = sql & " 'TotEntrg' FLOAT,"                   
  sql = sql & " 'TotUscg' FLOAT,"                   
  sql = sql & " 'RipFing' FLOAT"                     
  sql = sql & " );"

Codice: gambas [Seleziona]

Dim vTabCelle As New Variant[6]
-------- bla ----- bla ----- bla -------
 For Each RecTab
    iId += 1
    For i = 0 To 5
      vTabCelle[i] = RecTab[i]
    Next
    sql = "INSERT INTO riepmovg2 VALUES("
    sql &= iId & ", "     'iId
    sql &= vTabCelle[1] & ", '"    'DtCoMovg
    sql &= vTabCelle[2] & "', "    'StaDtMovg
    sql &= vTabCelle[3] & ", "    'TotEntrg
    sql &= vTabCelle[4] & ", "    'TotUscg
    sql &= vTabCelle[5] & ")";    'RipFing
    ApriDB.DBConnection.EXEC(sql)
 Next

Ho riprovato sia a scrivere dentro la tabella che a leggerne i contenuti. Ora la lettura funziona bene.   Devo ammettere che il Bug non era nel linguaggio, ma nel mio cervello.  ;D

Grazie Gianluigi.  :2birre:
 :ciao:
:ciao: