Autore Topic: cancellazione record in table sqlite3  (Letto 4268 volte)

g.paolo

  • Visitatore
cancellazione record in table sqlite3
« il: 06 Aprile 2008, 18:52:12 »
Ho una tabella con il campo ID autoincrementante e pertanto quando aggiungo un nuovo record, il campo ID aumenta di una unità rispetto al valore di count.
Supponiamo di volerne cancellare uno qualsiasi e pertanto il valore ID relativo verrà a mancare ed il totale record sarà inferiore di una unità, anche se l'ultimo record riporta un valore di ID maggiore del totale record.
Se provo ad aggiungere un nuovo record, il campo ID proposto come nuovo in modo automatico, riporta il numero del totale record +1, pertanto andrà a sovrapporsi all'ultimo record gia esistente.
Sia che provi ad usare count che mi porti sull'ultimo con movelast, stranamente non becca mai l'ultimo numero ID ma sempre il penultimo.
Vorrei sapere come fate voi che usate sqlite3 da qualche tempo a gestire tale problema.

g.paolo

  • Visitatore
Re: cancellazione record in table sqlite3
« Risposta #1 il: 06 Aprile 2008, 20:00:18 »
Ho fatto questa prova. In una tabella di 1910 records ho cancellato il n°1909 e quando vado a provare ad aggiungerne uno nuovo dopo aver usato il comando MOVELAST, mi propone il n°1910 che gia esiste, e se ci vado a scrivere perdo ovviamente i dati esistenti.
Se cancello anche il n°1908 e poi riaprendo la tabella dopo un MOVELAST provo ad aggiungerne un nuovo record, mi propone come nuovo il n°1115.
Ma che razza di comportamento è questo?
Non vorrei proprio essere costretto ogni volta ad fare un loop FOR EACH per capire qule è l'ID dell'ultimo record, anche perchè anche se non conosco bene l'inglese, mi sembra di capire che il MOVELAST posizioni realmente il puntatore sull'ultimo...... ma a quanto pare non è proprio così!
Qualcosa mi sfugge o esiste un comportamento non documentato di gambas con sqlite3 che non conosco???

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: cancellazione record in table sqlite3
« Risposta #2 il: 06 Aprile 2008, 22:03:57 »
scusa ma se id è autoincrementante a cosa ti servr fare un movelast per inserire un nuovo record?

a me lo inserisce in posizione corretta automaticamente con un semplice:
Codice: [Seleziona]
 


  $hconn.Open
  $hconn.Begin
 
  rarticoli = $hconn.Create("clienti")
 
    rarticoli!cli1 = "pippo"
    rarticoli!cli2 = "pippo11"
    rarticoli!cli3 = "pippo22"
    rarticoli!cli4 = "pippo33"
   
    rarticoli.Update
 
 
  $hConn.Commit
  $hconn.Close

g.paolo

  • Visitatore
Re: cancellazione record in table sqlite3
« Risposta #3 il: 07 Aprile 2008, 06:51:36 »
Sbaglio o tu con questo codice aggiungi ben 4 clienti in un colpo solo?

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: cancellazione record in table sqlite3
« Risposta #4 il: 07 Aprile 2008, 07:17:09 »
Sbagli. Inserisce 4 campi sempre nell'unico record aperto.
Connection.Create() inserisce infatti un nuovo record.

Ed ha ragione quando dice che è inutile usare MoveLast: con Create() il lavoro è fatto in automatico da SQLite. Anch'io uso campi autoincrementanti ma non ho mai avuto problemi.
Visita il mio sito personale: http://www.leonardomiliani.com

g.paolo

  • Visitatore
Re: cancellazione record in table sqlite3
« Risposta #5 il: 07 Aprile 2008, 07:23:57 »
Capito! Ma come si fa a conoscere il nuovo valore di ID del CREATE?

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: cancellazione record in table sqlite3
« Risposta #6 il: 07 Aprile 2008, 12:05:03 »
perconoscere l'id dell' ultimo record fai:

Codice: [Seleziona]
 
DIM hdata AS Result
DIM $hConn AS Connection
DIM sName AS String





$hConn = NEW Connection
  'TRY $hConn.Close

  sName = "pippo.db"

  WITH $hConn
    .Type = "sqlite3"
    .Host = User.Home
    .Login = ""
    .Password = ""
  END WITH

 $hConn.Name = sName
 $hConn.Open    
 $hconn.Begin
   
  hData = $hConn.Exec("SELECT * FROM clienti")
 
    hdata.MoveLast
   
    label1.text = hdata!id

g.paolo

  • Visitatore
Re: cancellazione record in table sqlite3
« Risposta #7 il: 07 Aprile 2008, 22:23:39 »
Pensavo ci fosse un'istruzione per trovarlo gia in fase di creazione, ma devo dedurre dalla tua risposta che non è proprio possibile. Si deve chiudere e riaprire la connessione dunque!

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: cancellazione record in table sqlite3
« Risposta #8 il: 07 Aprile 2008, 22:54:29 »
be no non devi chiudere e riaprire puoi benissimo utilizzare un semplice commit
dopo la creazione:
Codice: [Seleziona]
 DIM hdata AS Result
  DIM $hConn AS Connection
 DIM sName AS String

 $hConn = NEW Connection

 sName = "pippo.db"
 WITH $hConn
    .Type = "sqlite3"
    .Host = User.Home
    .Login = ""
    .Password = ""
  END WITH  

  $hConn.Name = sName
  $hConn.Open
  $hconn.Begin

       hdata = $hconn.Create("clienti")

         hdata!cli1 = "pippo"
         hdata!cli2 = "pippo"
         hdata!cli3 = "pippo"
         hdata!cli4 = "pippo"
 
     hdata.Update  

 $hconn.Commit      

       hData = $hConn.Exec("SELECT * FROM clienti")  
 
           hdata.MoveLast
           
            label1.text = hdata!id 'indica il numero dell' ultimo id        

           label2.text = hdata.Count 'indica il numero di record                

  $hconn.Close    



questo per leggere effettivamente il numero dell' id aggiunto

se invece devi fare una previsione e quindi sapere l' id del record prima di scriverlo
ti conviede dare prima l'istruzione SELECT
quindi:
 hdata.movelast

numero id futuro= (hdata!id)+1

g.paolo

  • Visitatore
Re: cancellazione record in table sqlite3
« Risposta #9 il: 07 Aprile 2008, 22:56:38 »
Molto bene fsurfing, questo semplifica anche il codice!
Seguirò il tuo consiglio, grazie!

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: cancellazione record in table sqlite3
« Risposta #10 il: 07 Aprile 2008, 23:04:42 »
scusa darth .... mi posteresti il codice con cui hai creato la tabella con indice
autoincrementante? :-)

g.paolo

  • Visitatore
Re: cancellazione record in table sqlite3
« Risposta #11 il: 07 Aprile 2008, 23:13:40 »
@fsurfing
Io non ho la necessità di creare la tabella da codice pertanto non sono costretto a creare la struttura dei campi. Avendo a disposizione files .csv contenenti i dati originali, li ho trasferiti automaticamente in un DB Sqlite3 usando Kexi, il quale mi propone sempre l'alternativa di usare un campo chiave tra quelli che ho oppure crearne uno automaticamente di nome ID.
Io scelgo quest'ultima strada, e sul campo ID autoincrementante non faccio nessuna operazione, ma mi è molto utile come contatore automatico anche se cancello records intermedi.
Credo comunque che per creare una table con un campo autoincrementante si debba usare un'istruzione simile a questa:
CREATE TABLE tabella ( KeyNumber int(3) NOT NULL auto_increment, stringa char(255) default NULL, PRIMARY KEY  (KeyNumber))

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: cancellazione record in table sqlite3
« Risposta #12 il: 07 Aprile 2008, 23:40:13 »
Meglio così:
Codice: [Seleziona]

CREATE TABLE 'tabella' ( 'KeyNumber' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 'stringa' CHAR(255) DEFAULT NULL);
Visita il mio sito personale: http://www.leonardomiliani.com

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.484
    • Mostra profilo
Re: cancellazione record in table sqlite3
« Risposta #13 il: 08 Aprile 2008, 13:39:13 »
infatti.. se non sbaglio con il codice postato da leo72 il campo id oltre che essere autoincrementante ha la particolarita di non lasciare "buchi" cancellando dei record intermedi, overro avendo 1000 record e cancellando ad esempio  il n° 500  dopo l' operazione di update e commit l'id dell' ultimo record sarà 998 e non 999 come in un autoincrementale creato con un istruzione del tipo

Codice: [Seleziona]
 CREATE TABLE 'tabella' ( 'KeyNumber' INTEGER NOT NULL PRIMARY KEY, 'stringa' CHAR(255) DEFAULT NULL);


questo lo scoperto ieri sera girovagando in http://www.sqlite.org/lang.html
un ottimo sito sul linguaggio SQLITE,  con un unico neo : è tutto in inglese.


Citazione
Avendo a disposizione files .csv contenenti i dati originali, li ho trasferiti automaticamente in un DB Sqlite3 usando Kexi, il quale mi propone sempre l'alternativa di usare un campo chiave tra quelli che ho oppure crearne uno automaticamente di nome ID.


io invece di usare kexi utilizzo sqlitebrowser che mi piace molto di più

inoltre se creo un db SQLITE3 con gambas con kexi non riesco ad aprirlo mentro con sqlitebrowser non ho nessun problema.Chissa se a  qualcun' altro succede o se solo a me?

g.paolo

  • Visitatore
Re: cancellazione record in table sqlite3
« Risposta #14 il: 08 Aprile 2008, 15:50:57 »
Oltre aquello che dici, Kexi ha un altro grosso difetto. Se modifico la struttura di una tabella, perdo completamente i dati, e questa è una gran cavolata che nemmeno il DB3 faceva!
Sqlitebrowser non l'ho mai provato visto che non si trova nei repository, ma forse da qualche parte il .deb o l'rpm lo becco, e poi lo provo. Ciao.