[R] SQLite : UPDATE

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
GMH
Niveau 5
Niveau 5
Messages : 181
Enregistré le : dim. 24 juin 2012 14:56
Status : Hors ligne

[R] SQLite : UPDATE

#1

Message par GMH »

Bonjour,

Le code suivant ne modifie pas la ligne sélectionnée dans une ListView qui fait appel à une base sqlite.

Sur ma GUI, j'ai une ListView et un formulaire permettant de modifier la base.
Un bouton [Modifier] envoie la fonction contenant le code suivant :

Code : Tout sélectionner


;Sélection par un clic de souris sur la ligne de la ListView à modifier :

if GUICtrlRead(GUICtrlRead($ListViewJournal)) <> 0  Then
	Local $message = ""
	$message = StringSplit(GUICtrlRead(GUICtrlRead($ListViewJournal)),"|")
	
;Appel à l'enregistrement correspondant de la base SQLite :

	Local $aResult, $hQuery
	_SQlite_Query (-1, "SELECT * FROM journal WHERE id='" & $message[1] &"';", $hQuery)
	_SQLite_FetchData ($hQuery, $aResult)
	_SQLite_QueryFinalize($hQuery)

;Remplissage du formulaire affichant les données de la ligne du ListView sélectionnée, destinées à être modifiées :

GUICtrlSetData($labelId, $aResult[0])
GUICtrlSetData($inputDate, $aResult[1])
GUICtrlSetData($inputLibelle, $aResult[2])
GUICtrlSetData($inputMoyen, $aResult[3])
GUICtrlSetData($inputCategorie, $aResult[4])
GUICtrlSetData($inputDebit, $aResult[5])
;$aResult[6] non modifié
GUICtrlSetData($inputCredit, $aResult[7])
Un bouton [Enregistrer] envoie la fonction contenant le code suivant destiné à modifier la base sQLite :

Code : Tout sélectionner

 
$Id = GuiCtrlRead($labelId)
$date = GuiCtrlRead($inputDate)
$libelle = GuiCtrlRead($inputLibelle)
$moyen = GuiCtrlRead($inputMoyen)
$categorie = GuiCtrlRead($inputCategorie)
$debit = GuiCtrlRead($inputDebit)
$rapprochement = ""
$credit = GuiCtrlRead($inputCredit)

 _SQLite_Exec(-1, "UPDATE journal SET " & _
							"id = '" & $Id & "', " & _
	                                    		"date = '" & $date & "', " & _
							"libelle = " & _SQLite_FastEscape($libelle) & ", " &  _
							"moyen = " & _SQLite_FastEscape($moyen) & ", " & _
							"categorie = " & _SQLite_FastEscape($categorie) & ", " & _
							"debit = '" & $debit & "', " & _
							"rapprochement = '" & $rapprochement & "', " & _
							"credit = '" & $credit & "' " & _
							"WHERE id = " & $Id & ";")
La modification de l'enregistrement ne se fait pas. Voyez-vous où je fais erreur ?

Je vous remercie de votre aide.
Modifié en dernier par GMH le mar. 04 févr. 2020 11:24, modifié 1 fois.

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2115
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] SQLite : UPDATE

#2

Message par jchd »

Quel code erreur au retour de ces fonctions ?

Si la colonne Id est numérique, la clause WHERE id = '1234' ne trouvera pas l'id 1234 ! Une chaîne n'est pas un nombre.

Dans l'update, inutile de mettre Id à jour puisque c'est la clause WHERE. Là aussi, n'encadrer par des quotes simples que les données chaîne (donc pas Id, Credit, Debit).

Par ailleurs, préférer de beaucoup _SQLite_GetRow ou *_GetTable[2d] à des séquences *Query, *Fetch, *Finalize.

Aussi, dans ce cas et par principe, englober le tout dans une transaction :
begin immediate;
select <ce qui m'intéresse>
<action utilisateur, dans un laps de temps raisonnable>
update/delete/insert <ce qu'il faut>
commit;

Le jour où il y a un autre processus qui tape dans la base simultanément, elle restera intègre ! A ce moment passer la BdD une fois pour toute en mode journal "WAL" et fixer un timeout approprié pour chaque connexion.

S'il y a possibilité que l'utilisateur parte manger, en vacances, aille dormir ou oublie de valider ses modifs, il faut procéder autrement : dans une transaction, lire les rangées concernées, les marquer "indisponibles" avec un code usager et éventuellement un timestamp et libérer la transaction.
Cela interdit la modif des ces rangées par un autre user ou process tant qu'elles sont marquées indisponibles.
A la validation des modifs, on vire le drapeau au passage pour rendre les données dispo pour les copains.

Variante : on laisse un temps raisonnable mais court pour effectuer et valider la modif, bloquant la base contre d'autres modifs entretemps.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

GMH
Niveau 5
Niveau 5
Messages : 181
Enregistré le : dim. 24 juin 2012 14:56
Status : Hors ligne

Re: [..] SQLite : UPDATE

#3

Message par GMH »

Bonjour jchd,

Je n'avais aucun message d'erreur. Simplement, la modification ne s'enregistrait pas dans la base.

Mon erreur était bien due au fait que mon $id était un string plutôt qu'un numeric. J'ai corrigé en ôtant les guillemets simples. J'ai fait de même pour les autres entrées numériques. Maintenant la fonction de modification fonctionne très bien.

J'ai lu attentivement toutes vos autres remarques et autres conseils. J'ai de quoi m'occuper ces prochaines heures pour comprendre et en tenir compte.

J'ai remarqué qu'une donnée numérique ne pouvait être vide dans la base SQLite. Zéro de rigueur ! Il n'y a pas moyen de faire accepter une donnée numérique vide par SQLite ? Sinon, je transformerai le zéro en une absence d'affichage dans ma ListView.

Je vous remercie énormément pour votre aide efficace. Grand merci pour le temps que vous consacrez à répondre à mes questions.

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2115
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] SQLite : UPDATE

#4

Message par jchd »

Qu'est-ce qu'une "donnée numérique vide" ?
La chaîne vide ne fait partie d'aucun ensemble de ce qu'il est convenu d'appeler les nombres (ici int64 et double).

Ceci dit, vous pouvez toujours utiliser NULL, qui en SQL signifie "je ne sais pas", pour stocker l'année de votre décès [ou du mien]. SQL est une "three-valued logic".

Si c'est pour stocker la valeur non utilisée entre crédit et débit en compta, le plus courant est de mettre 0.00 ; d'ailleurs SQLite stocke cette valeur très efficacement (comme 1, "", NULL).

Dernier point, je ne parlais pas d'un message d'erreur mais du contenu de la macro @error au retour de chaque fonction invoquée, à tester systématiquement lorsqu'il est possible qu'une fonction ne se passe pas "bien" !
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

GMH
Niveau 5
Niveau 5
Messages : 181
Enregistré le : dim. 24 juin 2012 14:56
Status : Hors ligne

Re: [R] SQLite : UPDATE

#5

Message par GMH »

Oui, du coup j'entre 0.00 dans le champ inutile, et par une condition, j'empêche l'affichage de ces valeurs nulles dans ma ListView pour plus de clarté.

Merci à vous.

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2115
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [R] SQLite : UPDATE

#6

Message par jchd »

En géréral, on évite de laisser un montant vide en compta et 0 est presque toujours affiché '0.00'.

Sinon, il suffit de stocker null si montant 0 et demander à SQL, c'est un langage puissant.
select id, date, ..., coalesce(printf(debit, ''), ..., coalesce(credit, ''), ... from journal where ...;

En fait, avec la version actuelle de SQLite.au3, il n'y a même pas besoin de coalesce() car le type NULL est renvoyé sous forme de chaîne vide. Perso je trouve que c'est une ânerie mais c'est ainsi que le code est écrit. Faut dire que le mot-clé NULL a été introduit tardivement, bien plus tard que l'UDF SQLite.

Si on veut un formatage texte direct, on peut faire ça :

select printf('%14.2f', 0.0) Résultat union all
select printf('%14.2f', -0.008) union all
select printf('%14.2f', 0.001) union all
select printf('%14.2f', 1.99999999) union all
select printf('%14.2f', -1234567890.12) union all
select printf('%14.2f', null) union all
select printf('%14.2f', '0.000000999') union all
select printf('%14.2f', -123.45) union all
select printf('%14.2f', '') union all
select printf('%14.2f', 'du texte') union alL
select printf('%14.2f', 1.99999999) union all
select printf('%14.2f', 3.1415926e5)
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

Répondre