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

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
begbegin
Messages : 7
Inscription : jeu. 04/oct./2018 8:12

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

Message 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
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

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

Message 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.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Marc56
Messages : 2148
Inscription : sam. 08/févr./2014 15:19

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

Message 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:
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

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

Message 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.
begbegin
Messages : 7
Inscription : jeu. 04/oct./2018 8:12

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

Message 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...) :)
Avatar de l’utilisateur
Mindphazer
Messages : 639
Inscription : mer. 24/août/2005 10:42

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

Message par Mindphazer »

Ah le GfA Basic !! Toute une (belle) époque !
Bienvenue au dinosaure !
Bureau : Win10 64bits
Maison : Macbook Pro M1 14" SSD 512 Go / Ram 16 Go - iPad Pro 32 Go (pour madame) - iPhone 15 Pro Max 256 Go
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

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

Message 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
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Marc56
Messages : 2148
Inscription : sam. 08/févr./2014 15:19

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

Message 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:
begbegin
Messages : 7
Inscription : jeu. 04/oct./2018 8:12

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

Message par begbegin »

Il y a toutes les procédures nécessaires à la gestion d'une DB...
Merci !
Répondre