IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Insérer des octets dans un champ BLOB


Sujet :

Lazarus Pascal

  1. #1
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut Insérer des octets dans un champ BLOB
    Bonjour à toutes et à tous,

    Je suis un pur débutant en base de données.

    J'utilise SqLite et j'ai cru comprendre que les instructions de gestion de cette base étaient les mêmes que pour SQL.

    Dans les instructions qui suivent, si je remplace les ????? de la dernière instruction par une valeur numérique, il n'y a pas de problème.

    Maintenant, je voudrais remplacer cette valeur numérique par une suite d'octets représentant par exemple les pixels d'une image. Je n'ai pas triouvé d'exemple sur le WEB. Qu'est-ce que j'écris à la place des ?????.

    Merci de votre aide.

    Pierre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
       SQLite3Connection.ExecuteDirect('CREATE TABLE tiles('+
                       ' x int,'+
                       ' y int,'+
                       ' z int,'+
                       ' image BLOB,'+
                       ' PRIMARY KEY (x, y, z));');
        SQLite3Connection.ExecuteDirect('INSERT INTO tiles VALUES (2, 3, 15,?????);

  2. #2
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 550
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 550
    Points : 3 916
    Points
    3 916
    Par défaut
    Salut

    En parcourant rapido les source du composant, je ne suis pas convaincu que cela soit faisable directement avec une composant TSQLite3Connection, des méthodes liées à la gestion des Blobs existent mais elles sont protégées et sans doute réservées à l'usage des composants d'accès.
    Piste : employer un composant TSQLQuery et accéder aux méthodes suivantes du champ TBlobField :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        procedure LoadFromFile(const FileName: string);
        procedure LoadFromStream(Stream: TStream);
        procedure SaveToFile(const FileName: string);
        procedure SaveToStream(Stream: TStream);
    Attention ces méthodes sont spécifiques aux objets TBlobField, il faut donc prendre des précautions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       (SqlQuery1.FieldByName('Image') as TBlobField).LoadFromFile('C:\MonImage.jpg');
    Pas le temps de donner une réponse plus détaillée, je file au boulot.

    @+

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  3. #3
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par e-ric Voir le message
    ... Attention ces méthodes sont spécifiques aux objets TBlobField, il faut donc prendre des précautions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       (SqlQuery1.FieldByName('Image') as TBlobField).LoadFromFile('C:\MonImage.jpg');
    ...
    Merci e-ric pour cette réponse.

    Comme je le disais dans mon premier post, je suis un débutant en base de données.

    Insérant l'instruction ci-dessus dans mon programme, cela ne fonctionne pas car il ne connait pas le champ 'Image'. Je suppose qu'il faut référencer ce champs par d'autres informations ... tiles.image ??? Je ne sais quoi donner comme information.

    Pour autant, j'ai essayé de charger directementun fichier en utilisant un TBlobField : ça plante. Voici ce que j'ai écrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var
      BlobField: TBlobField;
    begin
      BlobField:= TBlobField.Create(TComponent(Self));
      BlobField.SetFieldType(ftGraphic); // j'ai essayé avec divers ft..., ça plante tout pareil
      if OpenDialog.Execute then;
        BlobField.LoadFromFile(OpenDialog.FileName);
    Ça plante au chargement du fichier avec le message suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    le projet ... a levé une exception de class "External SIGSEGV" at Address ...
    Merci de votre aide.

    Pierre

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2003
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 33
    Points : 100
    Points
    100
    Par défaut
    Je répond pas à la question car j'ai pas eu le temps d'y songer mais simplement je pense qu'il est pas très judicieux de sauvegarder des images dans une BDD et encore moins dans une base SQLITE. Il vaut mieux sauvegarder les images dans un dossier et inscrire uniquement dans la BDD le nom du fichier avec d'autres infos pourquoi pas comme la taille, etc... Lightroom par exemple fonctionne comme çà et utilise une base SQLITE...

  5. #5
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par SoftChris Voir le message
    Je répond pas à la question car j'ai pas eu le temps d'y songer mais simplement je pense qu'il est pas très judicieux de sauvegarder des images dans une BDD et encore moins dans une base SQLITE....
    Ce n'est peut-être pas judicieux, mais je dois m'adapter à de l'existant (OruxMaps) qui l'utilise.

    Cordialement.

    Pierre

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Bonsoir,
    Sans connaître les composants d'accès aux données, il me semble que tu dois avoir besoin d'un intermédiaire. D'ailleurs, http://www.freepascal.org/docs-html/...blobfield.html dit :
    It should never be necessary to create an instance of TBlobField manually, a field of this class will be instantiated automatically for each BLOB field when a dataset is opened.
    On peut donc pê utiliser un DataSet dans lequel il n'y aurait que la ligne insérée (sans son BLOB) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SQLite3Connection.ExecuteDirect('CREATE TABLE tiles('+
                       ' x int,'+
                       ' y int,'+
                       ' z int,'+
                       ' image BLOB,'+
                       ' PRIMARY KEY (x, y, z));');
    SQLite3Connection.ExecuteDirect('INSERT INTO tiles (x, y, z) VALUES (2, 3, 15)');
      // après l'insertion, sélection de la ligne dans un dataset
    aDataSet.SQL := 'SELECT * FROM tiles WHERE rowid = last_insert_rowid'; // mais quel type de DataSet ???
      // puis interaction avec son champ BLOB
    aDataSet.FieldByName('image') as TBlobField).LoadFromFile('C:\MonImage.jpg');
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  7. #7
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    tourlourou, je te remercie de me donner des pistes, mais, un de mes gros problèmes actuellement, est que je suis vraiment un gros débutant en base de données. Cela veut dire que, dans le code que tu me donnes, je ne vois pas ce qu'est la variable "aDataSet". Je suppose que c'est une instance du composant TSQLQuery ?

    Ce que j'aimerais, afin de progresser pas à pas est que tu (ou bien d'autres intervenants) me dises pourquoi, dans l’instruction que tu m'as donnée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (SqlQuery1.FieldByName('Image') as TBlobField).LoadFromFile('C:\MonImage.jpg');
    mon application me dit : Field not found 'image' ?

    Dans le composant TSQLQuery que j'ai posé sur ma fiche, j'ai renseigné les champs :
    DataBase := SQLite3Connection;
    Transaction:= SQLTransaction;
    DataBase.DataBaseName:= mydatabase.db (nom de ma base de données)

    Apparemment, cela ne suffit pas. Je ne vois pas ce qu'il faut que j'indique pour que le champ'image' soit reconnu.

    Ci-après, le code de mon unité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    unit Unit1;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, sqlite3conn, sqldb, FileUtil, Forms, Controls, Graphics,
      Dialogs, StdCtrls, db;
     
    type
     
      { TForm1 }
     
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        OpenDialog: TOpenDialog;
        SQLite3Connection: TSQLite3Connection;
        SQLQuery: TSQLQuery;
        SQLTransaction: TSQLTransaction;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { private declarations }
        procedure StartDataBase;
      public
        { public declarations }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.lfm}
     
    { TForm1 }
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    {$IFDEF UNIX}  // Linux
      {$IFNDEF DARWIN}
        SQLiteLibraryName := './libsqlite3.so';
      {$ENDIF}
    {$ENDIF}
    {$IFDEF WINDOWS} // Windows
      SQLiteLibraryName := 'sqlite3.dll';
    {$ENDIF}
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      StartDataBase;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      if OpenDialog.Execute then
        (SQLQuery.FieldByName('image') as TBlobField).LoadFromFile(OpenDialog.FileName); // c'est là qua ça coïnce !
    //  SQLite3Connection.ExecuteDirect('INSERT INTO tiles (x, y, z, image)  VALUES (2, 3, 15, 32)');
    end;
     
    procedure TForm1.StartDataBase;
    var
      CreateTables: boolean;
      T: String;
    //  BlobField: TGraphicField;
    begin
    //  BlobField:= TGraphicField.Create(TComponent(Self));
     if FileExists('mydatabase.db') then
        DeleteFile('mydatabase.db');
      SQLite3Connection.DatabaseName:= 'mydatabase.db';
      SQLite3Connection.Open;
      SQLTransaction.Active:= True;
      SQLite3Connection.ExecuteDirect('CREATE TABLE android_metadata('+
                       ' locale TEXT);');
      SQLite3Connection.ExecuteDirect('INSERT INTO android_metadata VALUES (''fr_FR'')');
      SQLite3Connection.ExecuteDirect('CREATE TABLE tiles('+
                     ' x int,'+
                     ' y int,'+
                     ' z int,'+
                     ' image BLOB,'+
                     ' PRIMARY KEY (x, y, z));');
      SQLite3Connection.ExecuteDirect('CREATE INDEX IND on tiles(x,y,z)');
      SQLTransaction.Commit;
    end;
     
    end.
    Merci de votre aide.

    Pierre

  8. #8
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Une idée du pourquoi le champs 'image' n'est pas trouvé par l'instruction suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (SqlQuery1.FieldByName('Image') as TBlobField).LoadFromFile('C:\MonImage.jpg');
    Merci pour votre aide.

    Pierre

  9. #9
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Bonjour,
    Je suppose qu'un Query doit faire l'affaire.
    Dans ton code, ce Query est exploré à la recherche du champ 'image' alors que je ne vois pas de SQL pour le remplir. Pas de lignes => pas de champs... La seule connexion à la base ne le remplit pas.

    Donc qqch qui ressemble (schématiquement, en pseudocode) à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    SqlQuery1.SQL.Text := 'SELECT * FROM tiles'; // peuplera le dataset de tous les enregistrements de la table tiles
    SqlQuery1.Open; // quand on ouvrira l'ensemble de données
     
     // se positionner sur la bonne ligne
    Found:=False;
    SqlQuery1.First;
    While not SqlQuery1.EOF do
    begin
      if SqlQuery1.FieldByName('rowid').AsInteger = xxx 
      then begin
        Found:=True;
        Break;
      end
      else SqlQuery1.Next;
    end;
     
      // une fois trouvé
    if Found then (SqlQuery1.FieldByName('image') as TBlobField).LoadFromFile('C:\MonImage.jpg');
     
    SqlQuery1.Close;
    Il y a d'autres moyens de se positionner sur le bon enregistrement, dont on veut modifier ou visualiser des champs :
    - pê Locate ;
    - SQL qui ne retourne qu'une ligne, le plus simple !
    - utiliser Filter et Filtered
    - parcourir ligne par ligne avec First/Next/EOF
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  10. #10
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Bonjour tourlourou,

    Un grand merci de me faire avancer dans ce travail.

    Dans le code que tu me donnes, la boucle while n'est jamais parcourue ??

    J'ai utilisé un SQL n'utilisant qu'une ligne et ajouté la procédure SqlQuery.Insert :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      SqlQuery.SQL.Text := 'SELECT image FROM tiles'; // peuplera le dataset de image de la table tiles
      SqlQuery.Open; // quand on ouvrira l'ensemble de données
      if OpenDialog.Execute then
      begin
        SQLQuery.Insert;
        (SQLQuery.FieldByName('image') as TBlobField).LoadFromFile(OpenDialog.FileName);
    // Que faire maintenant pour insérer cette image dans la table ?
      end;
      SqlQuery.Close;
    Maintenant que j'ai chargé l'image, comment faire pour la retranscrire dans la table ?

    Tu m'as dit précédemment :

    It should never be necessary to create an instance of TBlobField manually, a field of this class will be instantiated automatically for each BLOB field when a dataset is opened.

    Comment accède t-on à cette instance ?

    Par ailleurs, j'ai vu que TBlobField a une propriété Value dont le contenu est une transposition du fichier chargé sous forme de texte. Peut-on utiliser cette valeur pour la passer comme suit dans la table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        T:= BlobField.Value; // comment accède t-on à cette instance
        SQLite3Connection.ExecuteDirect('INSERT INTO tiles (x, y, z, image)  VALUES (2, 3, 15,'+T+')');
        SQLTransaction.Commit;
    Merci de votre aide.

    Pierre

  11. #11
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2003
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 33
    Points : 100
    Points
    100
    Par défaut
    Salut,

    Bien que sauvegarder des images dans une BDD n'est pas une bonne idée et même franchement déconseillé j'ai fait un petit test et voilà le résultat pour enregistrer une image dans une BDD SQLITE et pour la lire ensuite dans un composant image, attention à mettre l'unité DB dans la clause Uses en haut de l'unité.

    J'utilise les composants standards de Lazarus à savoir :

    1 TSQLite3Connection
    1 TSQLTransaction
    1 TSQLQuery
    1 TOpenPictureDialog
    1 Timage
    et quelques boutons...

    Enregistrer une image JPG dans la BDD

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    procedure TMainForm.ButtonSavePictureClick(Sender: TObject);
    var
      Flux: TMemoryStream;
    begin
      if OpenPictureDialog1.Execute then
      begin
        try
          Flux := TMemoryStream.Create;
     
          Flux.LoadFromFile(OpenPictureDialog1.Filename);
     
          Flux.Position := 0;
     
          SQLQuery.SQL.Text := 'INSERT INTO T_PICTURE(F_picture) VALUES (:picture)';
     
          SQLQuery.Params.ParamByName('picture').LoadFromStream(Flux, ftBlob);
     
          SQLQuery.ExecSQL;
     
          SQLTransaction.Commit;
     
        finally
          Flux.Free;
        end;
      end;
    end;



    Afficher une image de la BDD en fonction de son index, j'ai choisi le 1 mais c'est à discrétion...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    procedure TMainForm.ButtonAffichePictureClick(Sender: TObject);
    var
      Flux: TMemoryStream;
    begin
      try
        Flux := TMemoryStream.Create;
        SQLQuery.SQL.Text := 'SELECT F_picture FROM T_PICTURE WHERE F_idx = 1';
        try
          SQLQuery.Open;
          if not SQLQuery.IsEmpty then
          begin
            (SQLQuery.FieldByName('F_picture') as tBlobField).SaveToStream(Flux);
            Flux.Position := 0;
            Image1.Picture.LoadFromStream(Flux);
          end;
        finally
          SQLQuery.Close;
        end;
      finally
        Flux.Free;
      end;
    end;


    Ci-joint la base de données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CREATE TABLE [T_PICTURE] (
      [F_idx] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
      [F_picture] BLOB NOT NULL);

  12. #12
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Je te remercie SoftChris pour ces morceaux de code que je vais essayer de mettre en œuvre.

    Citation Envoyé par SoftChris Voir le message
    ... Bien que sauvegarder des images dans une BDD n'est pas une bonne idée et même franchement déconseillé ...
    Si j'utilise cette méthode, c'est parce que je voudrais me faire un utilitaire de chargement de cartes pour l'application android OruxMaps qui utilise cette méthode.

    N'étant pas un spécialiste des bases de données, peux-tu m'expliquer (ou me donner un lien) pourquoi ce n'est pas une bonne idée, voire même franchement déconseillé.

    Cordialement.

    Pierre

  13. #13
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    SoftChris,

    J'ai mis en oeuvre les morceaux de code que tu m'as donné : c'est super, ça fonctionne du premier coup.

    Pour autant, je le répète je suis vraiment débutant en base de données, peux-tu m'expliquer quelques points :
    • à la ligne 14 du premier code, le nom de la valeur est ":picture",
    • à la ligne 16 de ce même code, tu utilises 'picture' pour ParamByName.

    Quel est, comment établit-on le rapport entre ces appellations et l'appellation F_picture donné au champ ?

    Merci pour ces renseignements.

    Pierre

  14. #14
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2003
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 33
    Points : 100
    Points
    100
    Par défaut
    Salut,

    Pour ce qui concerne l'enregistrement des images dans une BDD, il faut savoir que les images sont des fichiers très lourds et qu'on peut pas rechercher quoique ce soit dans ces fichiers. Par contre sauvegarder les images dans des dossiers structurés et enregistrer dans la BDD le nom du fichier (pour l'afficher dans un composant TImage par exemple), la taille, une note, des mots clés, etc.. est une bien meilleure méthode. Tous les sites de photoblog fonctionnent suivant ce principe. En fait une BDD sert à stocker des données et non des fichiers. Regarde ce lien par exemple :

    http://sqlpro.developpez.com/cours/stockerimages/

    Pour ce qui concerne le code et les lignes 14 et 16, on appelle çà des requêtes paramétrées, c'est dans certains cas obligatoire de procéder comme çà (dans ton cas par exemple) mais pas obligé.
    Tu peut nommer les variables après le ":" comme tu veux dans la mesure où tu met le même nom dans le paramètre (ParamByName).

    Un exemple, j'ai une BDD avec une table nommée T_MAIN avec les champs de type VARCHAR "F_name", "F_surname", "F_sex". j'insère des données de manière simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SQLQuery.SQL.Text := 'INSERT INTO T_MAIN (F_name, F_surname, F_sex) VALUES ('Martinez', 'Christian', 'M')';
    Même chose avec une requête paramétrée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SQLQuery.SQL.Text := 'INSERT INTO T_MAIN (F_name, F_surname, F_sex) VALUES (:nom, :prenom, :sexe)';
     
    SQLQuery.Params.ParamByName('nom').AsString := 'Martinez';
    SQLQuery.Params.ParamByName('prenom').AsString := 'Christian';
    SQLQuery.Params.ParamByName('sexe').AsString := 'M';
    C'est un peut la même chose et on dirait qu'on complique pour pas grand chose, en fait c'est beaucoup plus puissant et notamment dès qu'on manipule des champs autres que string, les dates par exemple.

  15. #15
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Merci SoftChris pour ces compléments d'information.

    Existe-t-il de documents décrivant cette syntaxe que tu utilise 'T_..., F_..., :...)

    Cordialement.

    Pierre

  16. #16
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2003
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 33
    Points : 100
    Points
    100
    Par défaut
    Salut,

    Oui il y a surement des tas de trucs pour nommer les choses mais il faut pas se formaliser avec çà, le code fonctionnera aussi bien... Pour ma part je fait précéder par un T_ lorsque c'est une table, par un F_ lorsque c'est un champ (Field), IDX lorsque c'est un index, etc... Il y en a qui déconseille l'emploie des majuscules, d'autre le contraire...

  17. #17
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par SoftChris Voir le message
    Salut,

    Oui il y a surement des tas de trucs pour nommer les choses mais il faut pas se formaliser avec çà, le code fonctionnera aussi bien... Pour ma part je fait précéder par un T_ lorsque c'est une table, par un F_ lorsque c'est un champ (Field), IDX lorsque c'est un index, etc... Il y en a qui déconseille l'emploie des majuscules, d'autre le contraire...
    Bien. Mais ce qui m'interpelle est, dans les deux lignes suivantes que tu as écrites, comment le "système" fait la relation entre un champ que tu appelles F_picture et les valeurs :picture et 'picture'.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SQLQuery.SQL.Text := 'INSERT INTO T_PICTURE(F_picture) VALUES (:picture)';
     
          SQLQuery.Params.ParamByName('picture').LoadFromStream(Flux, ftBlob);
    Cordialement.

    Pierre

  18. #18
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    Tu as ici plusieurs niveaux de noms :
    - F_Picture : nom d'un champ dans une table d'une base. Ce nom est utilisé dans les requêtes SQL comme SQLQuery.SQL.Text := 'INSERT INTO T_PICTURE(F_picture) VALUES (:picture)'; et compris par l'analyseur SQL du moteur de la base ;
    - :picture : déclaration destinée au Query d'un paramètre de nom 'picture' grâce au ':' qui le précède ; comprise par l'analyseur syntaxique du Query qui va créer un paramètre de nom 'picture' dans sa liste Params, et qui permettra de l'adresser à l'aide de ParamByName('picture') par exemple. Lors de la transmission de la requête à la base, ce paramètre est simplement remplacé par le Query par sa valeur.
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  19. #19
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2003
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 33
    Points : 100
    Points
    100
    Par défaut
    Pas mieux

  20. #20
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Je vous remercie pour ces compléments d'information.

    Cordialement.

    Pierre

Discussions similaires

  1. Insérer des octets dans un BLOB
    Par ChPr dans le forum SQLite
    Réponses: 3
    Dernier message: 08/11/2014, 09h36
  2. Impossible d'insérer des valeurs dans un champ
    Par Sixpounder dans le forum Paradox
    Réponses: 1
    Dernier message: 08/07/2011, 17h00
  3. Lecteur des fichiers présents dans un champ blob
    Par qmike dans le forum Langage
    Réponses: 0
    Dernier message: 21/07/2010, 14h58
  4. Insérer des octets dans un fichier
    Par Hell dans le forum Langage
    Réponses: 7
    Dernier message: 13/08/2008, 11h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo