Page 1 sur 1

Récupérer dans une DB un texte saisi avec StringGadget

Publié : jeu. 04/oct./2018 13:47
par begbegin
Bonjour,
Je débute avec ce super langage qu'est purebasic.
J'ai créé une fenêtre dans laquelle je saisis des données par le biais de StringGadget.
Puis, je veux les enregistrer par le biais d'une procédure dans une base de données SQLite préalablement créée.

Voilà la procédure SaveFicheClient :

Code : Tout sélectionner

Procedure CheckDatabaseUpdate(Database, Query$) 
   Result = DatabaseUpdate(Database, Query$) 
   If Result = 0 
      Debug DatabaseError() 
   EndIf 
    
   ProcedureReturn Result 
EndProcedure 


Procedure SaveFicheClient()
  
  If OpenDatabase(0, "diligences.sqlite", "", "")
    name.s = GetGadgetText(NOM_INPUT)
    surname.s = GetGadgetText(PRENOM_INPUT)
    CheckDatabaseUpdate(0, "INSERT INTO fiche_client (nom, prenom) VALUES ('"name"', '"surname"')") 
  EndIf
    
EndProcedure
Or, quand je compile je me prends un : "ligne 27, 'name' is not a valid operator", à hauteur de la ligne checkDatabaseUpdate dans la procédure SaveFicheClient.

Ma question : comment passer dans une requête SQLite ces saisies texte avec StringGagdet ?
Si quelqu'un a une ou LA solution, ce sera avec grand plasir. :)
Merci

Re: Récupérer dans une DB un texte saisi avec StringGadget

Publié : jeu. 04/oct./2018 14:33
par Micoute
Bonjour begbegin,

voici un programme que j'avais fait il y a bien longtemps, quand j'utilisais ce système de bases de données:

j'espère qu'il t'inspirera pour ton projet.

:arrow: Modération (falsam) : Code supprimé car beaucoup trop long pour un débutant. De plus il s'agissait de voir ce qui n'allait pas dans le code fourni par begbegin et non de lui fournir le code d'une application compléte.

Re: Récupérer dans une DB un texte saisi avec StringGadget

Publié : jeu. 04/oct./2018 15:25
par Marc56
Bienvenu begbegin :)

Tu simplement aligné chaîne de caractère et valeur sans faire de concaténation (+ en PB, . ou & dans d'autres)
Il faut faire ceci:

Code : Tout sélectionner

; Non
; CheckDatabaseUpdate(0, "INSERT INTO fiche_client (nom, prenom) VALUES ('"name"', '"surname"')")

; Oui
CheckDatabaseUpdate(0, "INSERT INTO fiche_client (nom, prenom) VALUES ('" + name + "', '" + surname + "')") 
Mais LA solution encore meilleure est d'utiliser les variables de liaison
https://www.purebasic.com/french/docume ... tring.html
Ta requête serait donc ainsi:

Code : Tout sélectionner

SetDatabaseString(0, 0, GetGadgetText(NOM_INPUT))
SetDatabaseString(0, 1, GetGadgetText(PRENOM_INPUT))

CheckDatabaseUpdate(0, "INSERT INTO fiche_client (nom, prenom) VALUES (?, ?)") 
Entre autres avantages cela permet de saisir des noms avec des espaces, ", ' etc
Ce n'est pas une invention PureBasic, cela existe dans tous les grands langages
https://en.wikipedia.org/wiki/Prepared_statement (PureBasic y est)

PS. indiques-nous quels autres langages tu pratiques, cela permettra de t'aider par analogie.
Tu peux aussi te créer une signature pour indiquer quelle version d'OS et quel matériel tu utilises.

:wink:

Re: Récupérer dans une DB un texte saisi avec StringGadget

Publié : jeu. 04/oct./2018 16:53
par boby
Voir même directement

Code : Tout sélectionner

CheckDatabaseUpdate(0, "INSERT INTO fiche_client (nom, prenom) VALUES ('" + name + "', '" + GetGadgetText(PRENOM_INPUT) + "')") 
/!\ Attention tout de même, comme l'as précisé Marc56, si ton StringGadget contiens un caractère comme ' ou tout autre forme de caractère "interprété" en SQL, il sera pris en compte par ta DB.

Re: Récupérer dans une DB un texte saisi avec StringGadget

Publié : ven. 05/oct./2018 5:38
par begbegin
Un grand merci pour ces réponses... et leur rapidité !
Je suis de la catégorie des "petits programmeurs" (rien de péjoratif), des "bidouilleurs" aurait-on dit à une autre époque. A m'amuser à faire des bouts de code plutôt en C...en assembleur Z80 aussi (séquence nostalgie).
J'ai découvert purebasic il y a peu, mais le charme a opéré tout de suite. Intuitivement on sent qu'on peut tirer beaucoup de ce langage, et de façon très très souple. ça donne des ailes et des envies de projets un peu plus conséquents. Et aussi de découvrir des basics (GFA etc.) sur des vielles machines (Atari, amiga...) :)

Re: Récupérer dans une DB un texte saisi avec StringGadget

Publié : ven. 05/oct./2018 8:25
par Mindphazer
Ah le GfA Basic !! Toute une (belle) époque !
Bienvenue au dinosaure !

Re: Récupérer dans une DB un texte saisi avec StringGadget

Publié : ven. 05/oct./2018 11:54
par falsam
@Boby & begbegin : La meilleure des réponses est celle de Marc56 :wink:

:idea: Information complémentaire sur les requêtes SQL préparées
https://www.purebasic.fr/french/viewtop ... 75#p191075

Re: Récupérer dans une DB un texte saisi avec StringGadget

Publié : ven. 05/oct./2018 13:12
par Marc56
Comme cadeau de bienvenue, un exemple qui montre quelques méthodes PureBasic, dont les requêtes préparées
Cet exemple n'est pas optimisé, mais réponds en même temps à un certains nombre de questions que se posent les nouveaux arrivants en PB venant d'autres langages :)
  • L'utilisation des requêtes préparées (Prepared statement) pour saisir tout type de caractère y compris apostrophes et guillemets.
  • La gestion des bases SQLite (création depuis zéro et utilisation)
  • La façon de vérifier l’existence d'une ressource (fichier, handle de fichier, connexion à une base de données) avant utilisation
  • Les énumérations qui permettent d'affecter des valeurs aux constantes en étant sûr de leur unicité
  • Les chaines de caractères avec séquences d'échappement ~"..."
  • La façon d'éviter les fautes de frappe en forçant la demande de définition de variable (EnableExplicit)
  • Comment gérer les raccourcis clavier
  • Remplir et vider un gadget liste liste
  • La boucle d'évènement principale (toujours une seule)
Exemple complet. Copier/coller/lancer
Saisir une chaine comme
You know what I'm "Happy"
Valider.
Tous les caractères sont bien stockés dans la base, y compris accents et guillemets

Code : Tout sélectionner

EnableExplicit

UseSQLiteDatabase()

Enumeration 
    #Win
    #Str_Edt
    #Btn_Submit
    #Lst_Rec
    #DB
    #Kbd_Return
EndEnumeration

OpenWindow    (#Win,         0,  0, 500, 300, "Test caractères spéciaux", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget  (#Str_Edt,    10, 10, 480,  20, "")
ButtonGadget  (#Btn_Submit, 10, 40, 480,  30, "Enregistrer dans la base")
ListViewGadget(#Lst_Rec,    10, 80, 480, 210)

; Le gadget actif est la zone de saisie
SetActiveGadget(#Str_Edt)
; Le bouton peut être validé par la toucvhe entrée
AddKeyboardShortcut(#Win, #PB_Shortcut_Return, #Kbd_Return)

; --- Création ou utilisation d'une base SQLite (dans %temp%)
; La variable est de type globale pour être accessible dans la procédure
Global DB_Name$ = GetTemporaryDirectory() + "DB_Test.sqlite"
If FileSize(DB_Name$) = -1 ; Fichier inexistant
    Debug "La base de test n'existe pas. Création"
    ; Pour créer une base SQL il faut commencer par créer un fichier vide
    If CreateFile(#DB, DB_Name$, #PB_UTF8)
        Debug "Fichier créé"
        CloseFile(#DB)
        ; Ensuite on ouvre ce fichier (vide) en mode mise à jour
        If OpenDatabase(#DB, DB_Name$, "", "")
            Debug "Connecté à la base " + GetFilePart(DB_Name$)
            If DatabaseUpdate(#DB, "CREATE TABLE test(test TEXT)")
                Debug "Table créée"
            Else
                Debug "Ne peux créer la table dans la base"
                Debug "Erreur: " + DatabaseError()
            EndIf
        EndIf
    Else
        Debug "Ne peut créer le fichier SQlite" : End
    EndIf
Else
    ; ~ devant une chaine permet d'utiliser les caractères d'échappement \n\r\t etc
    Debug ~"La base " + DB_Name$ + 
          ~" existe.\nLes données seront ajoutées"
EndIf



Procedure Load_DataBase()
    ; Charge les anciennes données si la base existe
    If OpenDatabase(#DB, DB_Name$, "", "")
        If DatabaseQuery(#DB, "SELECT * FROM test")
            Debug "Lecture OK"
            ; Grâce à la fonction DatabaseQuery() on peut lister la base ligne par ligne
            While NextDatabaseRow(#DB)
                ; Puis on ajoute simplement le contenu de la colonne 1 dans la liste
                AddGadgetItem(#Lst_Rec, -1, GetDatabaseString(#DB, 0))
            Wend  
        EndIf
    Else
        Debug "Pas d'anciennes données ou base de données"
        ProcedureReturn 
    EndIf
EndProcedure



Procedure Write_DataBase()
    ; --- Ecriture dans la base
    ; Si elle n'est pas ouverte, on l'ouvre
    If Not IsDatabase(#DB) : OpenDatabase(#DB, DB_Name$, "", "") : EndIf
    ; On prend ce que l'utilisateur a saisi
    Define Query_Input$ = GetGadgetText(#Str_Edt)
    ; On le met tel quel dans une zone mémoire
    SetDatabaseString(#DB, 0, Query_Input$)  
    ; ? va mettre tout le contenu dans la requète (y compris '") sans influencer la requête
    If DatabaseUpdate(#DB, "INSERT INTO test VALUES (?)")   
        Debug "INSERT OK [" + Query_Input$ + "]"
        ; Pour vérifier, je relis toute la base
        ; Vider le gadget car on va tout relire
        ClearGadgetItems(#Lst_Rec)
        ; Lire tous les champs
        If DatabaseQuery(#DB, "SELECT * FROM test")
            Debug "Lecture OK"
            ; Grâce à la fonction DatabaseQuery() on peut lister la base ligne par ligne
            While NextDatabaseRow(#DB)
                ; Puis on ajoute simplement le contenu de la colonne 1 dans la liste
                AddGadgetItem(#Lst_Rec, -1, GetDatabaseString(#DB, 0))
            Wend                       
        Else
            Debug "INSERT KO " + DatabaseError()
        EndIf
    EndIf    
    SetGadgetText(#Str_Edt, "")
EndProcedure

Load_DataBase()

Repeat
    Select WaitWindowEvent()
            
        Case #PB_Event_CloseWindow
            ; Si la base était ouverte, on la referme
            If IsDatabase(#DB)
                CloseDatabase(#DB)
            EndIf
            End
            
        Case #PB_Event_Gadget 
            If EventGadget() = #Btn_Submit
                Write_DataBase()
            EndIf      
            
        Case #PB_Event_Menu
            ; Un raccourci clavier est traité comme un évènement de type menu
            If EventMenu() = #Kbd_Return
                Write_DataBase()
            EndIf

    EndSelect
ForEver

End
Ce programme:
  • Créé une base SQLite (dans le répertoire temporaire)
  • Si la base existe, les données sont lues
  • Quand on saisi une ligne, elle est mise en base
  • La liste est vidée
  • La base est relue et la liste remplie à nouveau
(on peut se contenter d'ajouter juste la nouvelle ligne, mais là c'est pour expliquer au plus simple)

:wink:

Re: Récupérer dans une DB un texte saisi avec StringGadget

Publié : mar. 09/oct./2018 14:47
par begbegin
Il y a toutes les procédures nécessaires à la gestion d'une DB...
Merci !