Dovendo cancellare un record da una Tabella di DB di SQLite3, vorrei sapere se il record indicato nei parametri "WHERE" è stato trovato oppure no. Le istruzioni che uso normalmente sono:
RecTab = DB_Connection.EXEC("DELETE FROM prestmom WHERE DtSolPrestMom = '" & i_Data & "' and OraSolPrestMom = '" & i_Orario & "'")
IF NOT RecTab.Available THEN 'Se l'istruzione DELETE è stata eseguita correttamente. RecTab contiene "FALSE",
DB_Connection.Commit
ENDIF
Nella nuova necsssità non sono sicuro che il record sia presente nella tabella. Come risulta dal codice riportato sopra, l'avvenuta cancellazione del record da come esito "FALSE", cioè "NOT RecTab.Available", ma da pure "FALSE" qualora il record da cancellare non sia stato trovato.
Esiste un altro metodo per conoscere se il record da cancellare sia stato effettivamente trovato e cancellato?
Ho provato anche con:
TRY RecTab = DB_Connection.EXEC("DELETE FROM partmovv WHERE DtCoPartGlob = '" & i_dataCont & "' and DtSolPartGlob = '" & i_Data & "' and OraSolPartGlob = '" & i_Orario & "'")
IF ERROR THEN
Message.ERROR("Attenzione! -> Errore in " & Error.Backtrace[0] & " - n." & ERROR.Code & " - " & ERROR.Text & Chr(10) & Chr(10) & "durante la cancellazione record")
ENDIF
Ma, pur non esistendo il record da cancellare, non ho ottenuto alcun errore.
Naturalmente non mi interessano le soluzioni pratiche del tipo: controlla gli id presenti nella tabella prima e dopo l'istruzione "DELETE", oppure: ricerca il record prima della cancellazione per sapere se esiste e dopo per sapere se è stato effettivamente cancellato. Sono tutte soluzioni pratiche che conosco già.
:( :(
Non è che ti stai confondendo? Hai invertito il tuo modo di pensare. :)
Devi tener presente che RecTab.Available restituisce TRUE se il record c'è e FALSE se esso non c'è. Quel NOT secondo me ti sta facendo solo confondere.
Daccordissimo con la tua riflessione teorica sul RecTab.Available . Però essa non vale per l'istruzione DELETE, perché si comporta come se cercasse il record cancellato e fornisce sempre FALSE, sia che il record venga cancellato, sia che il record non venga trovato, perché inesistente. Ho voluto infatti essere certo della mia affermazione del post di apertura ed ho eseguito la seguente prova:
RecTab = DB_Connection.EXEC("DELETE FROM partmovv WHERE DtCoPartGlob = '" & i_dataCont & "' and DtSolPartGlob = '" & i_Data & "' and OraSolPartGlob = '" & i_Orario & "'")
IF RecTab.Available THEN
Message.Info("Record 'partmovv' valido")
ELSE
Message.Info("Record 'partmovv' non valido")
ENDIF
Come si può vedere dal codice riportato qui sopra, ho cambiato la "IF NOT RecTab.Available" in "IF RecTab.Available" ed il risultato ottenuto dopo la cancellazione del record é l'emissione del messaggio "Record 'partmovv' non valido", corrispondente alla condizione di FALSE. Ho ripetuto poi la prova tentando la cancellazione di un record inesistente ed ho ottenuto sempre lo stesso risultato: FALSE
Provare per ... credere.
:( :(
Io scomporrei il problema in 2 parti:
1) la ricerca del record;
2) la cancellazione.
So che crei del codice ridondante e doppio ma così sei sicuro dell'effettiva esecuzione dell'istruzione. Mi spiego.
RecTab = DB_Connection.EXEC("SELECT * FROM partmovv WHERE DtCoPartGlob = '" & i_dataCont & "' and DtSolPartGlob = '" & i_Data & "' and OraSolPartGlob = '" & i_Orario & "'")
IF RecTab.Available THEN
Message.Info("Record 'partmovv' valido")
RecTab = DB_Connection.EXEC("DELETE FROM partmovv WHERE DtCoPartGlob = '" & i_dataCont & "' and DtSolPartGlob = '" & i_Data & "' and OraSolPartGlob = '" & i_Orario & "'")
ELSE
Message.Info("Record 'partmovv' non valido")
ENDIF
@ leo72:
Se hai letto bene la discussione, avrai riscontrato che ciò che mi suggerisci tu é proprio quello che non volevo fare, ma che, ieri sera, durante i supplementari della finale mondiale di calcio, con un occhio alla partita ed uno al mio programma, ho deciso di fare. Solo che l'esempio da me riportato per una tabella, nel programma é replicato in ben 4 tabelle e la condizione si può verificare allorquando l'operatore, dopo avere inserito i movimenti dovesse, decidere di annullare tutto per intraprendere un'altro percorso. Però dai riscontri ottenuti in questa discussione ho capito che al momento non vi sono altre alternative. Riporto qui sotto, soltanto per completezza, il codice scritto per superare l'ostacolo:WITH
DB_Connection
.Type = "sqlite3"
.Host = VarGlob.$_DbPath
.Name = VarGlob.$_DbNome
.OPEN 'Apro il DB
END WITH
RecMovgg = DB_Connection.EXEC("SELECT * FROM movimgg WHERE DtCoMovgg = '" & i_dataCont & "'")
FOR EACH RecMovgg
RecPartMovv = DB_Connection.EXEC("SELECT * FROM partmovv WHERE DtCoPartGlob = '" & i_dataCont & "' and DtSolPartGlob = '" & i_Data & "' and OraSolPartGlob = '" & i_Orario & "'")
IF RecPartMovv.Available THEN
RecPartMovv = DB_Connection.EXEC("DELETE FROM partmovv WHERE DtCoPartGlob = '" & i_dataCont & "' and DtSolPartGlob = '" & i_Data & "' and OraSolPartGlob = '" & i_Orario & "'")
i_NumPartMovv += 1
DB_Connection.Commit
ELSE
RecPrestMom = DB_Connection.EXEC("SELECT * FROM prestmom WHERE DtSolPrestMom = '" & i_Data & "' and OraSolPrestMom = '" & i_Orario & "'")
IF RecPartMovv.Available THEN
RecPrestMom = DB_Connection.EXEC("DELETE FROM prestmom WHERE DtSolPrestMom = '" & i_Data & "' and OraSolPrestMom = '" & i_Orario & "'")
i_NumPrestMom += 1
DB_Connection.Commit
ENDIF
ENDIF
RecMovgg = DB_Connection.EXEC("DELETE FROM movimgg WHERE DtCoMovgg = '" & i_dataCont & "'")
i_NuMovG += 1
DB_Connection.Commit
NEXT
RecGGAperte = DB_Connection.EXEC("DELETE FROM ggaperte WHERE DtCoGGAp = '" & i_dataCont & "'")
DB_Connection.Commit
RecRiepNewRecDB = DB_Connection.Edit("riepnewrecdb", "NomeTab=&1", "movimgg")
i_Conta = RecRiepNewRecDB!NumIns - i_NuMovG
RecRiepNewRecDB = DB_Connection.EXEC("UPDATE riepnewrecdb SET NumIns =" & i_Conta & " WHERE NomeTab = 'movimgg'")
RecRiepNewRecDB = DB_Connection.Edit("riepnewrecdb", "NomeTab=&1", "partmovv")
i_Conta = RecRiepNewRecDB!NumIns - i_NumPartMovv
RecRiepNewRecDB = DB_Connection.EXEC("UPDATE riepnewrecdb SET NumIns =" & i_Conta & " WHERE NomeTab = 'partmovv'")
RecRiepNewRecDB = DB_Connection.Edit("riepnewrecdb", "NomeTab=&1", "prestmom")
i_Conta = RecRiepNewRecDB!NumIns - i_NumPrestMom
RecRiepNewRecDB = DB_Connection.EXEC("UPDATE riepnewrecdb SET NumIns =" & i_Conta & " WHERE NomeTab = 'prestmom'")
DB_Connection.Commit
RecRiepNewRecDB = DB_Connection.Edit("riepnewrecdb", "NomeTab=&1", "ggaperte")
i_Conta = RecRiepNewRecDB!NumIns - 1
RecRiepNewRecDB = DB_Connection.EXEC("UPDATE riepnewrecdb SET NumIns = " & i_Conta & " WHERE NomeTab = 'ggaperte'")
DB_Connection.Commit
Come vedi, non é poca cosa.
Tutti gli update elencati alla fine riguardano una tabella contenente le informazioni riepilogative su tutti gli inserimenti eseguiti nelle altre tabelle del DB. Esse vengono fornite all'avvio del programma per lasciare all'operatore libera scelta di riordinare la sequenza logica dei record nelle rispettive tabelle, selezionando quelle che più ne abbiano necessità, da una soltanto a tutte. ;)
Ciao.
Lo so che non volevi farlo ma, spesso, le cose noiose risolvono :)
Un modo per diminuire il codice potrebbe essere quello di utilizzare una stringa composta dalla parte comune della query:
Query = "FROM partmovv WHERE DtCoPartGlob = '" & i_dataCont & "' and DtSolPartGlob = '" & i_Data & "' and OraSolPartGlob = '" & i_Orario & "'"
RecPartMovv = DB_Connection.EXEC("SELECT * " & Query)
IF RecPartMovv.Available THEN
RecPartMovv = DB_Connection.EXEC("DELETE " & Query)
i_NumPartMovv += 1
DB_Connection.Commit
ecc....