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

Bases de données Delphi Discussion :

Champ ftBlob pièce jointe


Sujet :

Bases de données Delphi

  1. #1
    Membre expérimenté
    Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 417
    Par défaut Champ ftBlob pièce jointe
    Bonjour,

    Quelle méthode serait la plus appropriée pour stocker le nom et l'extension d'un fichier importés dans un champ ftBlob?

    Le seul hic, c'est quand on veut les extraire, encore faut-il se rappeler de l'extension du fichier importé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    { GetSize }
    function GetSize(const Bytes: Int64): String;
    const
      B = 1;
      KB = 1024 * B;
      MB = 1024 * KB;
    begin
      if Bytes > MB then
        Result := FormatFloat('#.## MB', Bytes / MB)
      else if Bytes > KB then
        Result := FormatFloat('#.## KB', Bytes / KB)
      else
        Result := FormatFloat('#.## Bytes', Bytes);
    end;
    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
    { Private : WMDropFiles }
    procedure TFFieldBlob.WMDropFiles(var WMDrop: TWMDropFiles);
    const
      MaxFileSize = 2097152; // Max 2 Mo
    var
      FileName: PChar;
      BlobStream: TStream;
      FileStream: TFileStream;
    begin
      try
        GetMem(FileName, MaxFileSize);
        DragQueryFile(WMDrop.drop, 0, FileName, MaxFileSize);
     
        try
          BlobStream := DataSet.CreateBlobStream(DBTable.SelectedField, bmWrite);
          FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
     
          if FileStream.Size < MaxFileSize then
          begin
            BlobStream.CopyFrom(FileStream, FileStream.Size);
            StatusBar.Panels[0].Text := ExtractFileName(FileName);
            StatusBar.Panels[2].Text := GetSize(BlobStream.Size);
          end
          else
            MyMessage(ERR_FileMaxSize, False); // Message : Fichier trop volumineux ! Max 2 Mo
     
          FreeAndNil(FileStream);
          FreeAndNil(BlobStream);
        except
          StatusBar.Panels[0].Text := EmptyStr;
          StatusBar.Panels[2].Text := EmptyStr;
          MyMessage(ERR_LoadFile, False); // Message : Impossible de charger le fichier spécifié !
        end;
     
        FreeMem(FileName);
      finally
        DragFinish(WMDrop.drop);
      end;
     
      WMDrop.Result := 0;
    end;
    Nom : Capture d'écran 2025-03-30 152200.png
Affichages : 176
Taille : 33,5 Ko

    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
    { ActBlobToFile Click }
    procedure TFFieldBlob.ActBlobToFileClick(Sender: TObject);
    var
      BlobStream: TStream;
      FileStream: TFileStream;
    begin
      BlobStream := DataSet.CreateBlobStream(DBTable.SelectedField, bmRead);
     
      if (BlobStream.Size > 0) and (scSaveDialog.Execute) then
      begin
        try
          FileStream := TFileStream.Create(scSaveDialog.FileName, fmCreate);
          FileStream.CopyFrom(BlobStream, BlobStream.Size);
          FreeAndNil(FileStream);
        except
          MyMessage(ERR_ExportFile, False); // Message : Impossible d'extraire le fichier !
        end;
      end;
     
      FreeAndNil(BlobStream);
    end;
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même. :aie:
    Ce n’est pas un bogue - c’est une fonctionnalité non documentée. :lahola:

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 049
    Par défaut
    sur les gestion des try

    c'est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Create
    try
      ...
    finally
      Free
    Et les except c'est à part.

    En dehors de ça, une ciolonne Name et une Colonne Content ça suffit
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre expérimenté
    Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 417
    Par défaut
    La seule chose qui pose problème, c'est qu'il est possible d'avoir plusieurs champs de type ftBlob.

    J'ai envisagé d'utiliser le système TMemIniFile dans un champ ftMemo.

    [Attachment]
    Nom du champ1 = File.pdf
    Nom du champ2 = File.rtf
    ...
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même. :aie:
    Ce n’est pas un bogue - c’est une fonctionnalité non documentée. :lahola:

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 579
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 579
    Billets dans le blog
    65
    Par défaut
    Et si tu analysais la signature (MIME) dans le stream avant ?
    les nouvelles versions de Delphi ont même une classe TMimeTypes dans l'unité System.Net.Mime sinon il y a la solution via indy (unité IdGlobalProtocols)

    suggestion, créer une fonction GetMime(astream : TblobStream) : string; qui te fournirai l'extension adhoc en étudiant les x premiers octets ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 049
    Par défaut
    En général, je ne fais jamais plusieurs colonnes blob

    Je fais une table séparée qui contient (ID, File, Content) et une table jointure N-N pour lier n'importe quel élément à un document
    Cela permet de gérer un nombre illimité de document attaché à un dossier patient, à un portefolio d'architecture, à un mail ... c'est un modèle universel


    La technique du Magic Number pourquoi pas mais se limiter autant, je ne comprends pas trop.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Membre expérimenté
    Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 417
    Par défaut
    il y a la solution via indy (unité IdGlobalProtocols)
    Cette solution est bien pensée, mais elle ne renvoie pas toutes les extensions.
    Exemple : Un fichier *.SQL ne renvoie pas d'extension, MIME = application:octet-stream.

    Par ailleurs, les types de fichiers (*.pdf, *.txt, *.htm, *.svg, *.csv, etc...) fonctionnent très bien.

    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
    uses
      IdGlobalProtocols;
     
    {$R *.dfm}
     
    function GetExtension(const MIMEType: String): String;
    begin
      Result := GetMIMEDefaultFileExt(MIMEType);
    end;
     
    function GetMIMEType(FileName: TFileName): String;
    var
      MIMEMap: TIdMIMETable;
    begin
      MIMEMap := TIdMIMETable.Create(true);
     
      try
        Result := MIMEMap.GetFileMIMEType(FileName);
      finally
        MIMEMap.Free;
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if OpenDialog1.Execute() then
      begin
        ShowMessage(GetExtension(GetMIMEType(OpenDialog1.FileName)));
      end;
    end;
    Néanmoins, en y regardant de plus près, cette méthode tourne en rond.

    La fonction GetFileMIMEType veut un fichier physique, donc avec l'extension du fichier, elle revoit son MIME et la fonction GetMIMEDefaultFileExt renvoie l'extension d'un fichier par son MIME.

    Il faudrait pouvoir récupérer un type MIME en fonction du contenu du BlobStream.

    La création d'une table pour gérer les pièces jointes est une idée judicieuse, moi qui étais parti pour gérer ça directement dans la table où il y a la ou les pièces jointes.
    Cela faciliterait la gestion de toutes les pièces jointes de toute les tables.

    - Nom Table
    - Nom de champs
    - Taille du fichier
    - Nom de fichier + Extension

    Je fais une table séparée qui contient (ID, File, Content) et une table jointure N-N pour lier n'importe quel élément à un document
    Donc, si je comprends bien, tu établis une table (Pièces jointes) où tu y stockes toutes les pièces jointes des tables, et tu assignes un ID à chaque pièce jointe, donc côté champ de table ftBlob tu lui écris l'ID ?

    Par conséquent, je pourrais échanger le champ Piece joint avec un type de ftGuid qui sera l'identifiant de mon fichier associé dans la table Pieces Jointes.

    Table Pieces Jointes
    ID = ftGuid
    FileName = ftString
    Content = ftBlob

    1) J'ajoute la pièce jointe dans la Table des Pieces Jointes
    2) J'ajoute le Guid dans le champ Pieces jointe
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même. :aie:
    Ce n’est pas un bogue - c’est une fonctionnalité non documentée. :lahola:

  7. #7
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    2 114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 2 114
    Par défaut
    L'avis des pros de la gestion des bases de données est...

    De ne jamais stocker dans une base de données des données sous forme de blob (image ou autres)

    Et pourquoi? Des données stockées sous forme de blob dans une base de données sont des données perdues parce que inutilisables, ce ne sont que des espaces mémoires qui ne sont pas accessibles aux requêtes de la base de données mais qui peuvent diminuer les performances de la base de données!!!

    Si on veut par exemple stocker des images, on stocke les images dans une structure externe et on enregistre que les liens pour y accéder dans la base de données...

  8. #8
    Expert confirmé
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 932
    Par défaut
    Citation Envoyé par Anselme45 Voir le message
    L'avis des pros de la gestion des bases de données est...

    De ne jamais stocker dans une base de données des données sous forme de blob (image ou autres)

    Et pourquoi? Des données stockées sous forme de blob dans une base de données sont des données perdues parce que inutilisables, ce ne sont que des espaces mémoires qui ne sont pas accessibles aux requêtes de la base de données mais qui peuvent diminuer les performances de la base de données!!!

    Si on veut par exemple stocker des images, on stocke les images dans une structure externe et on enregistre que les liens pour y accéder dans la base de données...
    Ce point de vue se défend, mais il faut alors blinder les sauvegardes pour ramasser la Base et ses périphériques; et blinder les restaurations pour éviter une Base qui pointerait dans le vide, ou des fichiers orphelins.
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet :resolu: - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

  9. #9
    Membre expérimenté
    Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 417
    Par défaut
    Citation Envoyé par Anselme45 Voir le message
    L'avis des pros de la gestion des bases de données est...

    De ne jamais stocker dans une base de données des données sous forme de blob (image ou autres)

    Et pourquoi? Des données stockées sous forme de blob dans une base de données sont des données perdues parce que inutilisables, ce ne sont que des espaces mémoires qui ne sont pas accessibles aux requêtes de la base de données mais qui peuvent diminuer les performances de la base de données!!!

    Si on veut par exemple stocker des images, on stocke les images dans une structure externe et on enregistre que les liens pour y accéder dans la base de données...
    Tout dépend comment on stocke la pièce jointe.
    J'ai laissé tomber le champ blod, après tout je limite la taille de la pièce jointe à 2 Mo ce qui n'est pas excessif, donc j'ai opté pour l'utilisation d'un champ Memo afin d'enregistrer directement les données du fichier dans ce champ, tout en effectuant une compression des données.

    Oui, c'est vrai, que ce soit du stockage interne ou des liens externes, il est possible qu'il y ait des problèmes dans les deux cas. (Lien corrompu ou erreur de stockage interne dans la base), d'où l'importance de la sauvegarde.

    D'où l'importance de pouvoir gérer l'intégralité des pièces jointes d'une base de donnes est d'effectuer des contrôles de lien ou de données corrompu.

    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même. :aie:
    Ce n’est pas un bogue - c’est une fonctionnalité non documentée. :lahola:

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Find n'affiche pas les champs des tables jointes
    Par didjac dans le forum Ruby on Rails
    Réponses: 3
    Dernier message: 02/06/2014, 08h20
  2. Ajouter un champ "nom pièce jointe"
    Par sunwalk dans le forum Outlook
    Réponses: 0
    Dernier message: 19/09/2013, 08h56
  3. SendMail avec Sheet en picèe jointe
    Par Lord_Chesseling dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 12/08/2012, 21h25
  4. mail avec picee jointe SQL 2005
    Par alpad dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 18/01/2011, 16h51
  5. Réponses: 0
    Dernier message: 27/05/2008, 13h28

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