Gambas-it

Archivi (sola lettura) => Programmazione (Gambas 2) => Topic aperto da: g.paolo - 06 Aprile 2008, 18:52:12

Titolo: cancellazione record in table sqlite3
Inserito da: g.paolo - 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.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 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???
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 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
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 07 Aprile 2008, 06:51:36
Sbaglio o tu con questo codice aggiungi ben 4 clienti in un colpo solo?
Titolo: Re: cancellazione record in table sqlite3
Inserito da: leo72 - 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.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 07 Aprile 2008, 07:23:57
Capito! Ma come si fa a conoscere il nuovo valore di ID del CREATE?
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 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
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 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!
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 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
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 07 Aprile 2008, 22:56:38
Molto bene fsurfing, questo semplifica anche il codice!
Seguirò il tuo consiglio, grazie!
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 07 Aprile 2008, 23:04:42
scusa darth .... mi posteresti il codice con cui hai creato la tabella con indice
autoincrementante? :-)
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 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))
Titolo: Re: cancellazione record in table sqlite3
Inserito da: leo72 - 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);
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 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?
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 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.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: md9327 - 08 Aprile 2008, 15:57:15
Per caso non viene chiusa la connessione ?
E' probabile che il file sqlite rimanga aperto per qualche motivo, non permettendone più la lettura da qualche altra applicazione che, invece, controlla il bit di chiusura.

Un consiglio per i campi autoincrement: se in ambiente multiutenza, nel range di tempo tra la lettura dell'ultimo valore, e la scrittura dello stesso incrementato, potrebbero esserci degli accessi contemporanei che rendono invalido lo sforzo. Se prendiamo il caso che il valore corrente sia 10, e predisponiamo il successivo inserimento con il valore 11, e se qualcuno nel frattempo chiede la stessa cosa, anche quest'ultimo imposterà il valore 11, per cui il database avrà due "11", incasinando così la chiave. Ovviamente, se è presente un controllo da parte del database (come su MySQL o PostgreSQL), l'ultimo record verrebbe rigettato, riportando un errore, ma in sqlite non sò cosa possa accadere...
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 08 Aprile 2008, 16:02:58
Ci avevo gia pensato infatti, e la tua osservazione cade proprio a fagiuolo!
Pensavo di aggiungere un campo boolean ad ogni table, e quando il primo lo apre in EDIT, la prima operazione che fa lo mette TRUE come impegnato, così gli altri possono solo leggerlo fintantochè le modifiche apportate non sono chiuse.
Non so se funzionerà, ma penso di provarci.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: md9327 - 08 Aprile 2008, 17:55:44
Bè, così in fondo simuli il lock del record...
Però fai sempre attenzione alle modifiche concorrenti...
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 08 Aprile 2008, 18:06:28
Bisogna proprio essere oltremodo sfigati per arrivare a registrare contemporaneamente il blocco nel medesimo microsecondo!
Io intendo infatti registrare il nuovo record vuoto con il flag di blocco prima di effettuare le modifiche finali e pertanto penso sia alquanto improbabile una sovrapposizione di eventi, non credi?
Nel momento in cui il secondo utente accede al medesimo record per attivare il proprio flag di blocco, trovandolo occupato gli viene ritornato il messaggio di indisponibilità e pertanto gli viene proposto il nuovo record seguente.
Se invece si tratta di EDIT, il primo che accede lo blocca e gli altri ricevono il mess di indisponibilità.
Dimmi dove fa acqua il mio ragionamento per cortesia.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: md9327 - 08 Aprile 2008, 18:15:19
Nessuna pecca nel tuo ragionamento logico, ma per quanto riguarda la sfiga ti faccio presente la "Legge di Murphy" e, comunque e a parte gli scherzi, il problema si verifica in percentuale proporzialmente al numero di utenti connessi. Ovviamente se sei solo tu, la cosa non si verifica.

La logica di locking e della contemporaneità degli eventi, è una logica abbastanza complessa, e comunque adottata da tutti i dbms più evoluti. Su sqlite non ho esperienza, per cui le mie parole possono essere buttate al cesso, se sqlite già prevede questa logica.

Ad ogni modo, la tua implementazione può andare bene.

Approvo ! :-)
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 08 Aprile 2008, 19:00:39
Grazie Gran Maestro, le tue parole mi confortano!
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 08 Aprile 2008, 19:21:32
scusate ma sqlite è un database locale per cui credo che il problema di due utenti che scrivano un record nello stesso istante non si può verificare a meno che un utente non utilizzi contemporaneamente due programmi.
secondo mettere una routine di blocco  all' interno di un programma è inutile
visto che il programma lo realizziamo noi ed eviteremo di lasciare procedure con database aperti.

Secondo me ogni procedura che accede al db deve sempre essere lei ad aprire la connessione e di conseguenza a chiuderla, evitando di avere una apertura della connessione a inizio programma e la chiusura a fine programma  :-)
Titolo: Re: cancellazione record in table sqlite3
Inserito da: leo72 - 08 Aprile 2008, 19:31:02
Per evitare problemi di sovrapposizione di accessi, penso basti dire al DB di utilizzare una connessione esclusiva con "BEGIN EXCLUSIVE". In questo modo ogni accesso successivo al DB verrà bloccato finché essa non sarà terminata.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 08 Aprile 2008, 20:03:54
@fsurfing
Se io metto il DB Sqlite su un server come backend ed installo i frontend sui client che ne elaborano i dati, non faccio nulla di più di quello che faccio ora con due file Access, uno sul server con i soli dati, ed uno sui client con il prg di gestione.
Quindi in tal caso il problema si pone eccome, a meno che qualcuno mi dica che non è possibile accedere ad un file SQlite3 nel modo che ho appena spiegato.

@Leo
E' una cosa che voglio proprio provare quella che hai detto; se così fosse penso che Sqlite si meriti qualche apprezzamento in più.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 08 Aprile 2008, 20:11:52
@darth, non vorrei fare il rompiscatole... ed è anche possibile che mi sbaglio ma mi pare di aver letto tempo fa da qualche parte (Preciso é! :lol: )che sqlite non fosse affatto consigliato per utilizzo in applicazioni client-server per questioni di sicurezza ( ad esempio non puoi impostare password e utente)ma solo per qpplicazioni stand-alone.
poi ti ripeto sono anche io un profano ma sicuramente ponendo il problema qualcuno  potrà chiarirci le idee :-)
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 08 Aprile 2008, 20:27:19
sqlite browser lo puoi trovare qui: http://sourceforge.net/projects/sqlitebrowser/

è semplicissimo, lo scarichi , lo decomprimi e lo utilizzi subito senza installarlo, vedrai che lo troverai meglio di kexi :-)
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 08 Aprile 2008, 22:06:23
Ti ringrazio per l'informazione circa il programma. Mo lo provo subito!
Per quanto concerne come dici tu le password e la sicurezza, queste le ho sempre gestite a livello di frontend e mai sul backend che comunque era protetto in modo completo sia dalla visualizzazione che dalla modifica, e quando dico visualizzazione mi riferisco al fatto che sul disco del server non lo vedi affatto.
La gestione della sicurezza da parte di questi database con le palle, mi ha sempre lasciato un po perplesso, perchè quando una cosa non sai come funziona, diffidi sempre.
Comunque, mai dire mai, quindi voglio provare anche con MySql.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 08 Aprile 2008, 23:56:44
:cappello: vedo che di server e affini ne sai molto più di me!

comunque tieni presente che i dati contenuti in db sqlite si leggono benissimo con un semplice editor esadecimale in quanto non vengono criptati
Titolo: Re: cancellazione record in table sqlite3
Inserito da: andy60 - 09 Aprile 2008, 06:56:52
Io uso l'editor del database di Gambas, anche quella è una strada. Per la creazione del db relazionale sto sperimentando Ombrello Kde, che non mi crea il database ma puo' esportare i comandi di creazione in una query mysql.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: leo72 - 09 Aprile 2008, 07:55:01
Il consiglio di usare SQLite solo per applicazioni stand-alone deriva dal fatto che non tratta i thread come gli altri DB. Quindi non ha una coda in cui inserisce le query e le esegue via via. Se ad esempio apro una transazione su una tabella per aggiungere dei dati dalla postazione A e poi vado a prendermi un caffé prima di salvare la transazione stessa, il collega sulla postazione B può modificare il DB prima di me e magari gli stessi dati a cui io stavo lavorando. Ecco perché o si utilizzano solo transazioni esclusive, in modo che dalla postazione B si abbia il messaggio di "DB occupato" oppure si crea a livello di codice un sistema di ticket in modo tale che non possano sovrapporsi 2 transazioni sugli stessi dati.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 09 Aprile 2008, 08:02:09
@fsurfing
Certo, questo lo so bene, ma conto di usare un software da mettere sul server per rendere invisibile la cartella in cui risiede il DB Sqlite3, in armonia col principio: "cio che non vedi, non stuzzica l'interesse!"
E' una prova ovviamente, quella che voglio fare, ma che personalmente ritengo più sicura di tanti metodi di protezione applicati a DB "visibili".

@leo
Penso che il tuo consiglio dell'EXCLUSIVE sia un buon metodo...da provare!
L'esempio che hai fatto è significativo, ed il pensare che nella "coda" ci sono transazioni tra loro contrastanti, non mi garba affatto, anche perchè in tal modo non mi è dato sapere a priori quale delle medesime avrà successo. Preferisco di gran lunga il metodo del blocco, così chi accede ad un record bloccato, attende tempi migliori, e se proprio lo vuol modificare, prima si informa circa le modifiche che gli altri fanno.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: md9327 - 09 Aprile 2008, 11:31:13
Vedo che questo discorso ha acceso un bel dibattito, ma alcuni a mio avviso hanno idee poco chiare sul concetto, anche dovute alla poca esperienza con i database.

Un tempo esisteva il DB3, che funzionava più o meno come sqlite, con qualcosina in più ma qualcosina in meno (es. non era SQL compliance...).
Questo motore, che poi era un driver come sqlite, non gestiva alcuna sicurezza (come sqlite), e non aveva fondamentalmente basi di controllo sugli accessi contemporanei. Questo si traduceva nel fatto che l'applicazione doveva a questo punto gestire essa stessa tutte le cose, mentre il db rimaneneva nel rango di puro e semplice archivio.
Però, come qualcuno ha fatto giustamente notare, il fatto che sqlite non gestisca nè sicurezza nè accessi contemporanei, obbliga il programmatore a mettere i suddetti a livello di programma.
Come pure accennato, non è detto che io stesso non possa lanciare due applicazioni in contemporanea (cosa che si faceva normalmente per test anche con il DB3), oppure che il database anche se gestito in modalità client-server tramite apposito portale, non debba comunque prevedere l'accesso contemporaneo di più utenti.
E' da tener presente che mettendo in opera un'applicazione che preveda un portale verso una rete, deve per forza di cosa gestire questi problemi.

Tutto il discorso resta comunque valido in ogni caso si preveda la possibilità di archiviare dati da più punti, mentre è sicuramente inutile in applicazione stand-alone; un esempio potrebbe essere l'utilizzo di sqlite come contenitore di dati di configurazione di un'applicazione (invece di un file...).

Attenzione quindi, ad affrontare in modo corretto ciò che si stà mettendo in opera.

Ovviamente il mio eè un consiglio spassionato...

Bye
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 09 Aprile 2008, 12:00:46
Sempre preciso il nostro Gran Maestro, e questo è bene.
L'importante è infatti partire con il piede giusto in modo da non trovarsi poi infognati in un "cul de sac"!
Conoscendo bene i limiti delle cose, si impara a gestirle opportunamente.
Pertanto prima di cimentarmi con DB tipo MySQL e company, voglio provare con Sqlite, anche perchè la mole di dati da gestire non sono centinaia di migliaia, ma solo qualche decina suddivisi in piu tabelle.
Rimane da vedere come si comporterà il DB in rete, in termini di velocità intendo, perchè anche questa cosa per me è tutta da scoprire.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: md9327 - 09 Aprile 2008, 12:37:04
La velocità in rete non dipende dal db, ma dalla rete stessa.

Se costruisci un programma in C, oppure in Gambas, a livello di interfaccia esterna, sempre se i driver sono fatti bene, la velocità è la stessa, nessuna differenza.

Tanto per essere precisi... :-P
Titolo: Re: cancellazione record in table sqlite3
Inserito da: leo72 - 09 Aprile 2008, 15:41:21
Sul posto di lavoro ho 2 PC entrambi con Ubuntu e collegati in rete tramite un modesto router. Su di uno c'è il database a cui accedo dalle 2 postazioni tramite NFS. Tralasciando il tempo perso per la connessione al DB, una volta che è "agganciato" lavora quasi come fosse in locale. Ovviamente, io memorizzo poche centinaia di byte per volta per cui le prestazioni in velocità sono assolutamente insignificanti per me.

Torno inoltre sul discorso del "giusto approccio" al DB accennato da md9327.
Facciamo un paio di esempi per far capire meglio il discorso:

1)
ho un DB in cui memorizzo solo dati in maniera sequenziale, esempio: le uscite di cassa. E' ovvio che qui la tabella che accoglie i dati è una semplice pila in cui io "verso" dentro i dati man mano che mi arrivano senza dovermi preoccupare di cosa sta facendo il collega sull'altra postazione, da cui sta registrando le sue uscite.
In questo caso non ho bisogno di nessun controllo perché non avrò mai la situazione in cui 2 utenti accedono agli stessi dati contemporaneamente.

2)
ho un DB in cui memorizzo i documenti di vendita che genero via via (fatture). In questo caso DEVO obbligatoriamente implementare un qualche tipo di controllo altrimenti potrei creare confusione nel DB. Prendiamo il caso in cui il cassiere della postazione A venda un articolo per cui il cliente vuole la fattura. A questo punto, apre la maschera di inserimento del documento ed il programma legge dal DB l'ultimo numero di fattura generato, es. 15, e numera il nuovo documento con 16. Il cassiere comincia a riempire la maschera del documento ma le voci da inserire sono molte e l'operazione richiede del tempo.
Adesso il cassiere della postazione B deve emettere un documento di vendita anch'egli. Apre la maschera ed il suo client pesca dal DB l'ultimo numero di documento generato per numerare la nuova fattura. Siccome però la transazione del cassiere sulla postazione A non è ancora stata conclusa e quindi il documento non è stato salvato e la numerazione aggiornata, il DB fornisce al cassiere della postazione B lo stesso numero, vale a dire 15. Poi il cassiere conclude la transazione prima del cassiere della postazione B e salva quindi nel database il documento 16 prima che lo faccia il cassiere della postazione A. Quest'ultimo, quando terminerà la sua transazione, creerà un altro documento numerato 16. Ecco quindi che si è presentato il problema se non è stato previsto un sovrapporsi di accessi.

Come si può risolvere? O con il BEGIN EXCLUSIVE oppure così, con una soluzione "casereccia" ma semplice ed efficace...
Dalla postazione principale, se parto per emettere una fattura, salvo sulla postazione secondaria un piccolo file nascosto che poi cancello al termine della transazione. Il client della postazione secondaria esegue un controllo ogni volta che l'operatore richiede l'emissione di una nuova fattura: se esiste quel file, avverte l'operatore che l'emissione di nuove fatture è momentaneamente bloccata!  
Semplice ma funzionale :ehm:
Titolo: Re: cancellazione record in table sqlite3
Inserito da: fsurfing - 09 Aprile 2008, 15:54:10
@ leo72 riprendendo il tuo esempio, quindi fintanto che il cassiere A fon finisce la fattura il cassiere B non può crearne un altra?
non è più semplice (come utilizzo)realizzare il programma in modo che il numero di fattura venga calcolato solamente durante l' operazione di salvataggio della stessa (ovvero a compilazione compiuta)con un opzione di accesso exclusive , in questo modo il tempo di utilizzo del bd per ogni operazione diventa minimo e l'utilizzo del db permette una quasi completa contemporaneità. :-)
Titolo: Re: cancellazione record in table sqlite3
Inserito da: md9327 - 09 Aprile 2008, 16:08:01
E' vero che la cosa viene ridotta, ma non eliminata; la casualità è sempre in agguato.

Come ha descritto leo, anticamente si usava un simile accorgimento, però sul database stesso, approntando opportunamente una tabella di numeri fattura prenotati. Anche questo approccio, però, aveva dei problemi, legati al fatto che un operatore poteva annullare la fattura che stava compilando, creando così dei buchi, che tra le altre cose non erano molto legali; diciamo che andavano a finire come fatture annullate.

Con un'approccio odierno è possibile, utilizzando ad esempio una sequence, far inserire il numero automaticamente dal motore del db, in fase di inserimento; però questo comunque implica sia un problema simile a quanto scritto sopra, sia un controllo di contemporaneità da parte del motore db. Quest'ultima cosa è sicuramente espletata dai database moderni, su sqlite non sò...

A parte l'ipotesi di gestire fatture, se non esistono problemi di mantenere una numerazione costante e senza buchi, l'approccio di cui sopra, ovvero la prenotazione dei numeri, può essere un'ipotesi trattabile, e anche abbastanza semplice da realizzare (basta una tabella e poco codice...).

Per l'approccio della modalità EXCLUSIVE avrei dei dubbi, legati più al fatto di gestire nel più breve tempo possibile il locking, altrimenti non lavora più nessuno. Su DB3, ad esempio, si usava un piccolo loop a tempo che analizzava la possibilità di modificare un record, e se entro il tempo previsto ci riusciva bene, altrimenti avvertiva l'utente che l'operazione non era possibile, proponendo un siccessivo tentativo.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 09 Aprile 2008, 18:19:51
Mi piace proprio questa discussione perchè stanno uscendo molte informazioni utilissime che spero possano servire molto anche a chi verrà piu avanti.
Tutto sommato, analizzando bene i dettagli, mi convinco sempre più che per il mio caso in cui non ho da lavorare con numeri fattura che esigono l'assenza di buchi, la soluzione che ho ventilato in precedenza circa la  prenotazione del record con il flag di blocco, possa essere adeguata al mio scopo.
Quando avrò fatto le prove del caso in sito, vi saprò dire come funziona o se sarà il caso che adotti una soluzione o un DB diversi.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: leo72 - 10 Aprile 2008, 07:28:04
Non aggiorno subito la numerazione delle fatture, questa operazione la compia solo quando l'utente preme effettivamente il pulsante di salvataggio. Altrimenti, se decidesse di annullare l'operazione, mi vedrei costretto a modificare nuovamente la numerazione salvata sul DB.

Però ho necessità di sapere subito che numero dare al documento: ecco perché blocco l'altro operatore.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: g.paolo - 10 Aprile 2008, 07:33:27
Molto utile il tuo chiarimento, per impieghi futuri da parte mia.
Titolo: Re: cancellazione record in table sqlite3
Inserito da: md9327 - 10 Aprile 2008, 14:17:52
Eheheheh, con questi discorsi ho riacceso antiche zone della mia memoria e, devo dire, mi viene quasi una lagrimuccia...  :-(

Bè, un bel rinfresco di idee, sicuramente saranno utili, specialmente a chi non ha mai affrontato questo tipo di problemi...

Bye