Si on commente le ReplaceString() du champ4 alors on obtient une erreur et pas d'enregistrement des données.
Personne n'est #Null, simplement on reste souvent trop concentré sur un seul point.
Il faut user et abuser de
Debug et
ShowVariableViewer() et voir ce que programme "voit"
Si tu ajoutes l'affichage de la requête avant envoi:
Code : Tout sélectionner
DATAS.s= "'"+CHAMP1$+"','"+CHAMP2$+"','"+CHAMP3$+"','"+CHAMP4$+"'"
;
Define SQL$ = "INSERT INTO TEST (Champ1, Champ2, Champ3, Champ4) VALUES ("+DATAS+")"
Debug SQL$
_DatabaseUpdate(OUT, SQL$)
Tu verra l'erreur: la requête trouve du texte après la fermeture de la chaine. Champ4. Le premier ' autour de champ4 ferme la chaine donc la suite semble en trop.
Code : Tout sélectionner
... 'résultat du traitement pour 'champ4'')
near "champ4": syntax error
d'où le message 'erreur de syntaxe proche de "champ4"
D'où l'intérêt des Prepared statement.
Suite:
À la base SQLite ne gère que 5 type de données TEXT, NUMERIC, INTEGER, REAL, BLOB. Sauf en mode stricte, mais pour l'instant ne t'en occupe pas, mets TEXT pour tout ce qui est du texte. Il se débrouille pour allouer l'espace comme il faut.
https://www.sqlite.org/datatype3.html
La partie
Prepared statement se traiterait comme ceci
Code : Tout sélectionner
SetDatabaseString(OUT, 0, "résultat du traitement pour champ1")
SetDatabaseString(OUT, 1, "résultat du traitement pour champ2")
SetDatabaseString(OUT, 2, "résultat du traitement pour champ3")
SetDatabaseString(OUT, 3, "résultat du traitement pour 'champ4'")
_DatabaseUpdate(OUT, "INSERT INTO TEST (Champ1, Champ2, Champ3, Champ4) VALUES (?, ?, ?, ?)")
Chaque '?' représente le contenu total d'une variable (ici du texte, sinon on utilise SetDatabaseInteger( etc))
SetDatabaseString() va donc transformer les caractères non gérés ( " ' ) et filtrer
Il faut donc juste veiller à les présenter dans l'ordre ou ils ont étés défini.
PS.
- Tu peux "echapper" une chaine comme en C SetDatabaseString(OUT, 5, ~"Hello \"Bonjour\" le monde")
- En SQL si tu saisi tous les champs d'une table dans l'ordre de la table, il est inutile de préciser les champs, tu peux donc résumer à:
- Si tu n'a pas besoin de traiter le résultat d'une requête avant la suivante, tu peux en passer plusieurs en une ligne avec un point-virgule comme séparateur (comme dans un script SQL)
Edit: Après test et modification de ton code.
J'ai créé un fichier texte de test et je le saucissonne avec
StringField (équivalent de SPLIT dans d'autres langages). Mon fichier texte de test contient 4 champs et plein de ' " ' " inside )
Code : Tout sélectionner
;;; === LECTURE DONNÉES TEXTE ===
While Eof(IN) = 0
entry$ = Trim(ReadString(IN))
If entry$ = #Null$
Continue
EndIf
;
; traitement des entrées.
;
SetDatabaseString(OUT, 0, StringField(entry$, 1, ","))
SetDatabaseString(OUT, 1, StringField(entry$, 2, ","))
SetDatabaseString(OUT, 2, StringField(entry$, 3, ","))
SetDatabaseString(OUT, 3, StringField(entry$, 4, ","))
_DatabaseUpdate(OUT, "INSERT INTO TEST VALUES (?, ?, ?, ?)")
Wend
;;; === FIN LECTURE DONNÉES TEXTE ===
(Oui, StringField est l'une des rares commande pour laquelle le premier élément est 1 et non pas 0)
