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

Firebird Discussion :

Insertion de tableaux dynamiques


Sujet :

Firebird

  1. #1
    Membre régulier
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    228
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 228
    Points : 113
    Points
    113
    Par défaut Insertion de tableaux dynamiques
    Bonjour,

    Je souhaite migrer une application dont les données sont contenues dans des fichiers binaires vers une bdd FireBird 3. Je connais le format des fichiers donc je peux en lire le contenu et effectuer mes insertions dans ma bdd.

    Je suis coincé sur un point: j'ai des données de type tableau dynamique (single) que je dois également importer dans ma bdd.

    J'ai remarqué que les tableaux dynamiques ne sont pas les bienvenues sous FB, je ne vois pas comment insérer mes tableaux dynamiques (dont je connais la longueur) dans la bdd ?

    Dois-je créer un fichier texte contenant ce tableau puis insérer ce fichier en tant que BLOB ?

    Merci pour vos retours.

    Lefju

  2. #2
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 377
    Points : 19 049
    Points
    19 049
    Par défaut
    Salut à tous.

    Citation Envoyé par lefju cabro
    les données sont contenues dans des fichiers binaires vers une bdd FireBird 3.
    Quand on dit binaire, c'est plutôt un gros bloc de données dont on ne peut pas faire la distinction entre les éléments qui la compose.
    Je ne comprends pas trop ce que vous essayez de faire, en parlant de binaire, à moins que vos données vont être rangées dans des colonnes de type "blob".

    Citation Envoyé par lefju cabro
    Je connais le format des fichiers donc je peux en lire le contenu et effectuer mes insertions dans ma bdd.
    Donc, ce n'est pas du binaire !

    A partir du moment où vous connaissez la structure de ce que vous allez extraire, il est facile de les ranger dans vos tables FireBird.
    Je rappelle que vos tables ne doivent pas être l'exacte représentation de vos fichiers.
    Une base de données repose sur le concept ensembliste, ce qui implique de respecter les formes normales.

    Citation Envoyé par lefju cabro
    Je suis coincé sur un point: j'ai des données de type tableau dynamique (single) que je dois également importer dans ma bdd.
    La notion de tableau n'existe pas dans le concept ensembliste.
    Pour charger un tableau dans une table, vous devez connaitre son identifiant et la donnée qui est rattachée à son identifiant.

    Le concept de tableau dans le SGBDR FireBird est contraire à la première forme normale :
    Est en première forme normale, une relation (ayant par définition une clé) dont les attributs possèdent tous une valeur sémantiquement atomique ; Une autre définition serait : un attribut est dit « atomique » si aucune subdivision de l'information initiale n'apporte une information supplémentaire ou complémentaire.
    Hormi la théorie, et la conception de la base, il existe un solution qui consiste à passer par la notion firebird de table externe.
    Vous décrivez la structure de votre fichier, en indiquant tous les séparateurs et ensuite vous charger votre fichier dans la table FireBird.

    Il serait intéressant de connaitre la structure auquelle vous êtes confrontées (votre fichier), ainsi que la table FireBird dont vous désirez charger.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  3. #3
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par lefju cabro Voir le message
    J'ai remarqué que les tableaux dynamiques ne sont pas les bienvenues sous FB, je ne vois pas comment insérer mes tableaux dynamiques (dont je connais la longueur) dans la bdd ?
    ...
    Dois-je créer un fichier texte contenant ce tableau puis insérer ce fichier en tant que BLOB ?
    Je ne discuterai pas de la première forme normale.
    Les tableaux, effectivement type de données permis par Firebird car fork d'Interbase, existent. De là à pouvoir les remplir et les utiliser en SQL (je met de côté le via programmation) il y a un pas qui n'a jamais été franchi : pas d'API. Les développeurs Firebird laissent la porte ouverte, il me semble d'ailleurs avoir lu que si quelqu'un apportait un exemple concret, non gérable via la première forme normale, ils accepterait peut-être de s'y pencher.

    Qu'est-il entendu exactement par "Binaire" ? Quelque chose qui n'est pas du texte lisible ? il suffit d'utiliser un Blob subtype 0 en charge à une application de gérer ensuite la chose
    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

  4. #4
    Membre régulier
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    228
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 228
    Points : 113
    Points
    113
    Par défaut
    Bonjour Artemus24 et SergioMaster,

    Merci pour vos réponses.

    Il serait intéressant de connaitre la structure auquelle vous êtes confrontées (votre fichier), ainsi que la table FireBird dont vous désirez charger.
    La structure des éléments contenus dans les fichiers sont de type R_INFOS. Je sais que les fichiers contiennent x éléments de type R_INFOS, donc je peux facilement lire 1 à 1 ces éléments pour les insérer en BDD.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      R_INFOS= record
        no1: Integer ; //longueur de tab1 = longueur de tab2 = longueur de tab 3
        Indic1: Integer ; 
        Indic2: Integer ; 
        Indic3: Single ;
        tab1: array of Single ;
        tab2: array of Single ;
        tab3: array of Single ;
      end ;
    Je ne sais pas encore comment sera structurée ma BDD mais je pensais simplement à une table INFOS contenant les champs Indic1, Indic2 et Indic3 et mes 3 tableaux (sous je ne sais quelle type).

    Hormi la théorie, et la conception de la base, il existe un solution qui consiste à passer par la notion firebird de table externe.
    Késako une table externe ?

    Je peux avoir 1 millier d'éléments R_INFOS à insérer dans ma BDD. Les tables externes peuvent-elle être la solution ?

    Merci

    Lefju

  5. #5
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 377
    Points : 19 049
    Points
    19 049
    Par défaut
    Salut à tous.

    Je réponds à la question qui consiste à charger une table à partir d'un fichier contenant des chaînes de caractères.
    Chaque chaîne de caractères contient d'une manière concaténée et séparée par un point-virgule ';', la liste des données.
    Ce fichier "import.txt" est de longueur fixe, et est de 40 caractères. Voici son chargement dans une table FireBird :
    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
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    CREATE DATABASE '..\Data\Base.fdb' page_size 4096 DEFAULT CHARACTER SET WIN1252;
     
    -- =====================
    -- Création table 'test'
    -- =====================
     
    CREATE TABLE test (
      id    smallint generated by default as identity not null primary key,
      clef  varchar(10)  not null,
      ind   smallint     not null,
      elem  varchar(06)  not null
    );
     
    -- ===============================
    -- Création table externe 'Import'
    -- ===============================
     
    CREATE TABLE Import external 'e:/23.FireBird/30.Table_Externe/Ex_05/Import.txt' (
      libelle char(40),
      CRLF    char(02)
    );
     
    -- =====================
    -- Vidage table 'Import'
    -- =====================
     
    select libelle from Import;
     
    LIBELLE
    ========================================
    nombre;un;deux;trois;quatre;cinq;six
    couleur;rouge;vert;jaune
    alphabet;alpha;beta;gamma;delta
     
     
    -- ============================
    -- Création Procédure 'remplir'
    -- ============================
     
    set term $$ ;
     
    create procedure remplir
    as
      declare clef    varchar(10)  default null;
      declare ind     smallint     default 0;
      declare elem    varchar(06)  default null;
     
      declare newpos  integer      default 0;
      declare oldpos  integer      default 0;
      declare token   char(01)     default ';';
      declare result  char(255)    default null;
      declare input   char(40)     default null;
      declare arret   integer      default 0;
     
      declare tab cursor for (select libelle from Import);
    begin
      open tab;
     
      fetch tab into input;
     
      while (row_count > 0) do
      begin
        clef   = null;
        ind    = 1;
        elem   = null;
     
        oldpos = 1;
        newpos = 1;
        arret  = 0;
     
        while (arret=0) do
        begin
          newpos = position(token, input, oldpos);
     
          if (newpos > 0) then
          begin
            result = substring(input from oldpos for newpos - oldpos);
            oldpos = newpos + 1;
          end
          else
          begin
            result = substring(input from oldpos);
            arret = 1;
          end
     
          if (clef is null) then clef = trim(cast(result as varchar(255)));
          else
          begin
            elem = trim(cast(result as varchar(255)));
            insert into test (clef,ind,elem) values (:clef,:ind,:elem);
            ind = ind + 1;
          end
        end
     
        fetch tab into input;
      end
     
      close tab;
    end$$
     
    set term ; $$
     
    -- =============================
    -- Exécution Procédure 'remplir'
    -- =============================
     
    execute procedure remplir;
     
    -- =========
    -- Nettoyage
    -- =========
     
    drop procedure remplir;
     
    commit;
     
    drop table Import;
     
    -- ===================
    -- Vidage Table 'Test'
    -- ===================
     
    select * from test;
     
         ID CLEF           IND ELEM
    ======= ========== ======= ======
          1 nombre           1 un
          2 nombre           2 deux
          3 nombre           3 trois
          4 nombre           4 quatre
          5 nombre           5 cinq
          6 nombre           6 six
          7 couleur          1 rouge
          8 couleur          2 vert
          9 couleur          3 jaune
         10 alphabet         1 alpha
         11 alphabet         2 beta
         12 alphabet         3 gamma
         13 alphabet         4 delta
     
     
    exit;
     
    Appuyez sur une touche pour continuer...
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  6. #6
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 377
    Points : 19 049
    Points
    19 049
    Par défaut
    Salut à tous.

    Mauvaise nouvelle lefju cabro, on ne peut pas utiliser le type array directement dans une table externe :
    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
    CREATE TABLE Export external 'e:\23.FireBird\30.Table_Externe\Ex_05\Export_2.txt'
    (  no1     integer,
       indic1  integer,
       indic2  integer,
       indic3  integer,
       tab1    integer [5],
       tab2    integer [5],
       tab3    integer [5],
       CRLF    char(02)
     
    );
    Statement failed, SQLSTATE = HY004
    unsuccessful metadata update
    -CREATE TABLE EXPORT failed
    -SQL error code = -607
    -Invalid command
    -Data type ARRAY is not supported for EXTERNAL TABLES. Relation 'EXPORT', field 'TAB1'
    After line 5 in file Base_2.sql
    Voici un exemple d'utilisation de table externe :
    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
    -- ===============================
    -- Création table externe 'Export'
    -- ===============================
     
    drop table Export;
     
    CREATE TABLE Export external 'e:\23.FireBird\30.Table_Externe\Ex_05\Export_2.txt'
    (  no1     smallint,
       indic1  smallint,
       indic2  smallint,
       indic3  smallint,
       CRLF    char(02)
     
    );
     
    commit;
     
    -- =====================
    -- Vidage table 'Export'
    -- =====================
     
    select * from Export;
     
        NO1  INDIC1  INDIC2  INDIC3 CRLF
    ======= ======= ======= ======= ======
         15       4       5       6
     
         15       6       8      19
     
         15      15      11      18
     
         15       2      22      17
     
    exit;
     
    Appuyez sur une touche pour continuer...
    La colonne CRLF contient le caractère "carriage return" (décimal : 13) et "line feed" (décimal : 10).
    C'est pourquoi, à l'affichage du select, il y a un saut de ligne.

    Dans le fichier, pour un smallint, la saisie a été faite sur deux octets, dont le poids fort est à droite tandis que le poids faible est à gauche.
    C'est exactement l'inverse sous IBM gros système et du coup, cela m'a un peu perturbé dans la construction du fichier "export.txt".

    Afin de mieux comprendre comment j'ai créé ce fichier, voici une image de celui-ci avec les caractères lisibles et reconnaissables dans une table ASCII.



    Comment résoudre le problème du tableau ?
    Il faut définir chaque élément du tableau comme étant une colonne à part entière.

    Autre problème, c'est la longueur variable du tableau. Pour l'exploiter avec des tables externes, le tableau doit être définie à sa taille maximale.
    Sinon, cela risque de provoque un décalage à l'affichage des lignes dans les select.
    C'est-à-dire qu'une partie de la ligne suivante peut se retrouver à la fin de la première ligne courante.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  7. #7
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    La forme normale implique dans le cas présent non pas une mais à minima deux tables supplémentaires (ici je considère qu'un élément principal peut avoir plusieurs RDATA

    PRINCIPALE(IDPRINCIPALE ....)
    RDATALEVEL(IDPRINCIPALE,IDRDATA,no1,indic1, indic2,indic3)
    ARRAYS(IDPRINCIPALE,IDRDATA,NOARRAY,INDICE,VALEUR)
    Avec bien sûr des relations et contraintes entre tables

    Maintenant, comme je l'ai écrit, tout dépend si l'on veut faire des opérations via SQL sur ces valeurs ou pas. Si on veut faire des opérations avec les valeurs il faut en passer par la forme "normale" a contrario si ces opérations ne se font que intra-application un blob sub_type 0 peut très bien faire l'affaire voire même un blob type texte si le RDATA est transformé en JSON. (ce RDATA me fait tout à fait penser à JSON on y retrouve souvent ce type de structure et ce sans avoir besoin d'indiquer de dimensions, chaque array pouvant avoir des dimensions différentes). D'un point de vue programmation ça tient la route.

    Pour moi, les tables externes sont à écarter.

    Une option programmation+type Array dans la table+SQL est envisageable avec des UDF bien sûr, mais je n'ai jamais franchi ce pas
    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

  8. #8
    Membre régulier
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    228
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 228
    Points : 113
    Points
    113
    Par défaut
    Bonjour Artemus24 et SergioMaster,

    Merci, vos réponses sont très détaillées et votre niveau en BDD Pour tout vous dire je ne comprends pas tout...

    PRINCIPALE(IDPRINCIPALE ....)
    RDATALEVEL(IDPRINCIPALE,IDRDATA,no1,indic1, indic2,indic3)
    ARRAYS(IDPRINCIPALE,IDRDATA,NOARRAY,INDICE,VALEUR)
    Avec bien sûr des relations et contraintes entre tables
    Si je comprends bien, dans la table ARRAYS j'aurai une ligne = 1 valeur de mon tableau (par exemple tab1[51]) ? Si j'utilise ce modèle, je devrais passer par des tables externes cf tuto ?

    Si on veut faire des opérations avec les valeurs il faut en passer par la forme "normale" a contrario si ces opérations ne se font que intra-application un blob sub_type 0 peut très bien faire l'affaire voire même un blob type texte si le RDATA est transformé en JSON
    Je ne fais pas d'opérations/calculs SQL sur les valeurs des tableaux: le tableau sera intégralement chargé dans un objet et c'est sur cet objet que je ferai mes calculs. De ce fait je peux utiliser un BLOB. En gardant le modèle précédent mais avec ARRAYS_BLOB remplaçant ARRAYS, le nouveau modèle serait:
    ARRAYS_BLOB(IDPRINCIPALE,IDRDATA,NOARRAY,TAB_BLOB)

    C'est cohérent ?

    Merci

    Lefju

  9. #9
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Re
    Citation Envoyé par lefju cabro Voir le message
    Si je comprends bien, dans la table ARRAYS j'aurai une ligne = 1 valeur de mon tableau (par exemple tab1[51]) ?
    Exactement
    Si j'utilise ce modèle, je devrais passer par des tables externes cf tuto ?
    non, je ne vois pas l'utilité des tables externes dans ce cas, mais bon cela reste quand même hyper théorique, comment sont stockés ces arrays actuellement ?
    de plus la copie de BLOB par SQL j'ai des doutes dans ce cas, il faudrait que ce soit du texte, il faudra certainement plutôt faire un programme pour alimenter ces données

    Je ne fais pas d'opérations/calculs SQL sur les valeurs des tableaux
    donc un blob peut suffire
    le tableau sera intégralement chargé dans un objet et c'est sur cet objet que je ferai mes calculs
    en plus un objet! sachant qu'un objet Delphi ( Pascal ou C++) peut très facilement se transformer en JSON et vice-versa un blob text peut fonctionner à fond ! (JSON.ObjecttoJSONString)

    De ce fait je peux utiliser un BLOB.
    excatement
    En gardant le modèle précédent mais avec ARRAYS_BLOB remplaçant ARRAYS, le nouveau modèle serait:
    ARRAYS_BLOB(IDPRINCIPALE,IDRDATA,NOARRAY,TAB_BLOB)
    C'est cohérent ?
    A mon avis oui, mais en utilisant une structure JSON (je sais j'insiste un peu ) même pas besoin de passer à la forme "normale"
    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

  10. #10
    Membre régulier
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    228
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 228
    Points : 113
    Points
    113
    Par défaut
    Merci SergioMaster pour ton message.

    non, je ne vois pas l'utilité des tables externes dans ce cas, mais bon cela reste quand même hyper théorique, comment sont stockés ces arrays actuellement ?
    Ces arrays sont stockés dans des fichiers ci-dessous la procédure de lecture (ça remplit toujours le même objet mais bon c'est pour l'exemple...):
    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
      // Nb de R_INFOS dans le fichier
      FileRead (fd, Nb, SizeOf (Integer)) ;
      // Parcourt les R_INFOS
      for NumInfos:= 0 to Nb-1 do
      begin
        // Longueur de tab1 = longueur de tab2 = longueur de tab 3
        FileRead (fd, no1, SizeOf (Integer)) ;
        // Indic1
        FileRead (fd, Indic1, SizeOf (Integer)) ;
        // Indic2
        FileRead (fd, Indic2, SizeOf (Integer)) ;
        // Indic3
        FileRead (fd, Indic3, SizeOf (Single)) ;
     
        // Dimensionne les tab
        SetLength (tab1,  no1+1) ;
        SetLength (tab2,  no1+1) ;
        SetLength (tab3,  no1+1) ;
     
        // Remplit tab1
        FileRead (_fd, tab1[1], no1 * SizeOf (Single)) ;
        // Remplit tab2
        FileRead (_fd, tab2[1], no1 * SizeOf (Single)) ;
        // Remplit tab3
        FileRead (_fd, tab3[1], no1 * SizeOf (Single)) ;
      end;
    Certains de mes tableaux ont plus de 1 million de valeurs, je pense stocker le tout dans un blob.

    Tu parles (souvent ) de JSON, en quoi serait-ce utile dans mon cas ? Je suis désolé de poser cette question mais je suis néophyte.

    Merci

    Lefju

  11. #11
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par lefju cabro Voir le message
    Tu parles de JSON, en quoi serait-ce utile dans mon cas ?
    A mon avis le blob au format text avec JSON correspondrai parfaitement pour tes objets. JSON c'est en fait un format permettant de partager des données et ce quelque soit le langage, la plateforme etc.. le XML pourrait aussi faire l'affaire d'ailleurs

    Là on déborde sensu stricto de Firebird donc je ne vais pas me lancer dans de grandes explications (surtout qu'il y a JSON et JSON , en fait JSON "format delphi" et JSON "format universel" je viens de voir ça lors d'un visionnage d'une séance coderage XII : Customising Datasnap method output - Bob Swart).

    Dans un de mes tutoriels sur les Livebindings j'aborde très légèrement le sujet. En fait, j'y utilise un fichier texte pour stocker des données.

    Dans ton cas, en gros et à débattre dans le forum delphi, je procéderai de la manière suivante :
    Je crée une première classe R_Infos avec propriétés et tutti quanti...
    je crée ensuite un TObjectList<R_Infos>
    que je remplis (en fonction de ton fichier)
    une seule ligne de code me fourni alors un texte JSON
    je balance ce texte dans un BlobStream pour l'enregistrer dans la BDD (ouf on revient à Firebird )
    cerise sur le gâteau tout tes arrays pourraient même avoir des tailles différentes au besoin
    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

  12. #12
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 377
    Points : 19 049
    Points
    19 049
    Par défaut
    Salut à tous.

    Citation Envoyé par lefju cabro
    Dois-je créer un fichier texte contenant ce tableau puis insérer ce fichier en tant que BLOB ?
    Mon premier exemple (message #5) répond au chargement d'une table FireBird, en passant par un fichier texte.
    Ce fichier texte se présente sous la forme de lignes dont la longueur est fixe. Dans mon exemple la longueur est de 40 caractères.

    La procédure stockée permet de récupérer chaque chaîne par un point-virgule et de la stocker dans la table FireBird.
    C'est hyper simple à faire et cela peut répondre à votre problème si la nécessité est de passer par ce type de fichier texte, au cas où vous ne pourriez pas résoudre votre problème de tableau (Array).

    Le second exemple (message #6) est l'usage d'une table externe, beaucoup plus compliqué à mettre en oeuvre car vous devez faire correspondre chaque structure du fichier, à un type de FireBird.
    J'utilise le type "smallint" qui est codifié sur deux octets, pour illustrer cet exemple.

    Citation Envoyé par lefju cabro
    je ne vois pas comment insérer mes tableaux dynamiques (dont je connais la longueur) dans la bdd ?
    La question est double :
    1) comment stocker, disons cette structure, dans la base de données ?
    2) comment l'exploiter par la suite ?

    SergioMaster souligne un point fort intéressant :
    Citation Envoyé par SergioMaster
    Maintenant, comme je l'ai écrit, tout dépend si l'on veut faire des opérations via SQL sur ces valeurs ou pas.
    a) Autrement dit, la base de données sert-elle à faire du stockage ?
    b) Ou bien avez-vous besoin de faire des opérations de type SQL ?

    Dans le cas a), l'usage d'un blob serait parfait, car cette colonne (ou structure dans notre cas) serait exploitable uniquement à l'intérieur d'un programme.
    Dans la cas b), il faut passer par la forme normale (règle N°1) qui consiste à créer une ligne par éléments de votre tableau.
    Il faudra revoir la modélisation de votre base de données, et les implications que cela nécessite dans le cas de votre migration de données.

    Citation Envoyé par SergioMaster
    Pour moi, les tables externes sont à écarter.
    Il s'agit d'une migration de données !

    Quand je faisais des migrations sous gros-systèmes, genre passer de BULL à IBM, nous faisions cela en convertissant nos données dans un format lisible (texte).
    Bien sûr, la structure des données était éclater afin de la rendre facilement exploitable, sans rencontrer des problèmes liés à la codification ou à une organisation quelconque.
    Convertir du texte de l'ASCII en EBCDIC était un jeu d'enfant.
    Ensuite, le chargement des fichiers se faisait au travers d'un programme cobol qui lisait chaque enregistrement et venait les introduire dans les tables DB2 en les convertissant dans le bon type.

    Avec MySql, le format qui est fréquemment utilisé est celui des fichiers de type Excel au format ".csv".
    Dans le cas de Firebird, il n'existe pas d'outils permettant de faire cela, sauf en passant par des tables externes, comme dans mon premier exemple.

    Citation Envoyé par lefju cabro
    Ces arrays sont stockés dans des fichiers ci-dessous la procédure de lecture (ça remplit toujours le même objet mais bon c'est pour l'exemple...):
    D'après votre exemple (message #10), il s'agit d'un enregistrement ayant toujours la même structure, mais de longueur variable.
    Si je peux me permettre de vous faire une remarque, il y a une erreur ci-après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Dimensionne les tab
        SetLength (tab1,  no1+1) ;
        SetLength (tab2,  no1+1) ;
        SetLength (tab3,  no1+1) ;
    
        // Remplit tab1
        FileRead (_fd, tab1[1], no1 * SizeOf (Single)) ;
        // Remplit tab2
        FileRead (_fd, tab2[1], no1 * SizeOf (Single)) ;
        // Remplit tab3
        FileRead (_fd, tab3[1], no1 * SizeOf (Single)) ;
    Vous ne pouvez pas définir la taille de vos trois tableaux, en mettant à chaque fois "no1".
    Logiquement, j'aurai plutôt écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Dimensionne les tab
        SetLength (tab1,  Indic1+1) ;
        SetLength (tab2,  Indic2+1) ;
        SetLength (tab3,  Indic3+1) ;
     
        // Remplit tab1
        FileRead (_fd, tab1[1], Indic1 * SizeOf (Single)) ;
        // Remplit tab2
        FileRead (_fd, tab2[1], Indic2 * SizeOf (Single)) ;
        // Remplit tab3
        FileRead (_fd, tab3[1], Indic3 * SizeOf (Single)) ;
    Autre remarque : chaque structure de vos tableaux (tab1, tab2, tab3) dépend essentiellement de leur taille (Indic1, Indic2, Indic3).
    En plus du blob qui va contenir la structure du tableau, vous devez aussi stocker la longueur correspondante.

    On ne sait rien de vos tableaux, à savoir s'ils sont à 1, 2 ou plusieurs dimensions.

    Pourquoi mettre trois tableaux dans un enregistrement ?
    Il aurait été plus judicieux de créer un enregistrement, composée de la longueur de la structure et ensuite la structure du tableau.
    Mais dans ce cas là, le tableau serait à 1 dimension.

    D'où mon interrogation, avez-vous toujours trois tableaux renseignés dans un enregistrement ?
    A moins de me tromper, avez-vous une matrice de 3 lignes et N colonnes ? Chaque ligne étant un tableau.

    Citation Envoyé par SergioMaster
    A mon avis le blob au format text avec JSON correspondrai parfaitement pour tes objets.
    Je ne voie pas l'intérêt d'utilise json car la structure de base du tableau est "integer", c'est-à-dire toujours le même type.
    En faisant une mise en forme au format json, la volumétrie de la conversion serait bien plus importante, sans rien apporter de plus.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  13. #13
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par Artemus24 Voir le message
    Je ne voie pas l'intérêt d'utilise json car la structure de base du tableau est "integer", c'est-à-dire toujours le même type.
    En faisant une mise en forme au format json, la volumétrie de la conversion serait bien plus importante, sans rien apporter de plus.
    Exact, sauf que ainsi la structure en est plus facilement convertible et plus souple. On peut aussi bien sur utiliser un blob binaire ce que j'ai indiqué également et d'un point de vue programmeur on utiliserai alors une autre technique dont j'ai oublié l'existence et même le nom le ne fait pas encore son effet ce matin

    Pour en revenir aux tables externes, celles-ci ne peuvent contenir des blobs https://firebirdsql.org/file/documen...5-ddl-tbl.html
    Citation Envoyé par extrait
    The columns of a table stored in an external file can be of any type except BLOB or ARRAY
    cela est du entre autre à la manière dont sont gérés les blobs (en gros un pointeur vers un endroit de stockage hors table sensu stricto). On ne peut même pas traiter les données comme un varchar(32767) car qui dit valeurs numériques peut dire 0 et donc x00 et donc fin de chaine.

    A mon avis, passer les données en masse est plus que compromis hors programme ou UDF (mais UDF c'est quelque part un programme).
    Après, le choix du format de stockage devient plus une question d'usage et praticité qu'autre choses.

    Au fait en parlant de première forme normale comment justifier alors des blibliothèques proposant des fonctions spatiales où une colonne contient des ensembles de coordonnées (n°ligne, Tpoint(x,y,z))
    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

  14. #14
    Membre régulier
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    228
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 228
    Points : 113
    Points
    113
    Par défaut
    Bonjour,

    a) Autrement dit, la base de données sert-elle à faire du stockage ?
    b) Ou bien avez-vous besoin de faire des opérations de type SQL ?

    Dans le cas a), l'usage d'un blob serait parfait, car cette colonne (ou structure dans notre cas) serait exploitable uniquement à l'intérieur d'un programme.
    C'est le cas a) qui m'intéresse.

    Vous ne pouvez pas définir la taille de vos trois tableaux, en mettant à chaque fois "no1".
    Mes tableaux sont de dimensions identiques de taille no1 mais ils ne contiennent pas les même données.
    Indic1/2/3 sont des indicateurs scalaires.


    On ne sait rien de vos tableaux, à savoir s'ils sont à 1, 2 ou plusieurs dimensions.

    Pourquoi mettre trois tableaux dans un enregistrement ?
    Il aurait été plus judicieux de créer un enregistrement, composée de la longueur de la structure et ensuite la structure du tableau.
    Mais dans ce cas là, le tableau serait à 1 dimension.
    Mes tableaux sont à 1 dimension. Mes 3 tableaux sont dans un enregistrement afin d'avoir simultanément mes indicateurs (indic1/2/3) et tableaux pour effectuer mes traitements sur les données de cet enregistrement.

    D'où mon interrogation, avez-vous toujours trois tableaux renseignés dans un enregistrement ?
    Tous mes tableaux sont renseignés

    Je pense tester un modèle BDD avec/sans JSON.

    Merci à vous Artemus24 et SergioMaster pour vos conseils et explications: je vais pouvoir avancer sur mon projet mais surtout j'ai pu (re)voir de nouvelles approches (json, table externe...)

    Lefju

  15. #15
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 377
    Points : 19 049
    Points
    19 049
    Par défaut
    Salut à tous.

    Citation Envoyé par SergioMaster
    Exact, sauf que ainsi la structure en est plus facilement convertible et plus souple.
    Oui, enfin, ça dépend du contenu de la structure et aussi la façon dont on va l'utiliser.

    Citation Envoyé par SergioMaster
    d'un point de vue programmeur on utiliserai alors une autre technique dont j'ai oublié l'existence et même le nom
    Je ne voie pas de quoi vous parlez ?

    Citation Envoyé par SergioMaster
    Pour en revenir aux tables externes, ...
    Les tables externes reposent sur le chargement des tables FireBird à partir d'un fichier contenant que du texte. C'est mon premier exemple.
    Dans l'autre cas (le second exemple), cela peut être utile pour des structures simples ne nécessitant pas de procédures stockées pour récupérer les données.
    Je trouve cela d'une utilité douteuse, pour mon second exemple. Il me faudrait un cas concret afin de voir la difficulté et sa mise en oeuvre.

    Citation Envoyé par SergioMaster
    Après, le choix du format de stockage devient plus une question d'usage et praticité qu'autre choses.
    D'accord avec vous, et cela conditionne la façon d'on on va exploiter ces données par la suite.
    D'où l'utilité de passer par un "fileread" dans un programme, qui est plus simple, plutôt que de faire une table externe.

    Citation Envoyé par SergioMaster
    Au fait en parlant de première forme normale comment justifier alors des bibliothèques proposant des fonctions spatiales où une colonne contient des ensembles de coordonnées (n°ligne, Tpoint(x,y,z))
    La première forme normale s'applique à la répétition d'une même colonne dans la ligne, et non à la structure du type qui constitue la colonne.
    Sinon, il faudrait mettre un caractère par ligne, quand celui-ci compose une chaîne de caractères. Et cela deviendrait compliquer à gérer cela dans un programme.

    Citation Envoyé par lefju cabro
    Mes tableaux sont de dimensions identiques de taille no1 mais ils ne contiennent pas les même données.
    Normalement, pour définir un enregistrement de longueur variable, on ne procède pas ainsi.
    On définit en premier un integer contenant la longueur des données qui vont suivre. Et en second, les données, sous forme d'un bloc.
    Ce bloc sera déposé dans une structure complexe de votre programme. L'identification de la structure et sa longueur sont les seules informations utiles à connaitre !

    C'est pourquoi, il est inutile de procéder comme vous le faite. Un seul readfile est utile pour charger vos données et les mettre dans la structure définitives pour les exploiter par la suite.
    Mais bon, c'est votre choix, et il est hors de propos de parler de cela dans le forum consacré à FireBird.

    Bonne continuation, lefju cabro !

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  16. #16
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par Artemus24 Voir le message
    Je ne voie pas de quoi vous parlez ?
    C'est une solution purement RAD Studio (Delphi/C++), il m'a fallu du temps pour retrouver cette fonctionnalité que je n'utilise pas : les champs de type agregat.
    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

  17. #17
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 377
    Points : 19 049
    Points
    19 049
    Par défaut
    Salut SergioMaster.

    Rad Studio est un outil de développement multiplateforme.
    Qu'est-ce que "les champs de type agregat" ?

    Je ne voie pas trop le rapport avec la problématique de lefju cabro ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  18. #18
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par Artemus24 Voir le message
    Rad Studio est un outil de développement multiplateforme.
    Oui mais qui utilise Delphi (pascal) ou C++ comme langage voilà pourquoi j'ai indiqué rad studio avec en parenthèse les langages, or il s'avère que Lefju Cabro utilise ce dernier.
    Qu'est-ce que les champs de type agregat ?
    à part la preuve que je l'utilise si peu que je me suis trompé d'intitulé ? en fait je voulais parler de champs composés et de type CalcInterne
    Je ne voie pas trop le rapport avec la problématique de lefju cabro ?
    Je l'ai dit, ce sont des solutions programmes, rien à voir avec Firebird encore moins avec des tables externes sauf à créer (et on en revient à de la programmation) ses propres UDF (UDF selon la vision Firebird/interbase du terme)
    Donc des propos hors forum Firebird
    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

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

Discussions similaires

  1. tableaux dynamiques
    Par Mynautor dans le forum C++
    Réponses: 23
    Dernier message: 12/02/2005, 02h45
  2. Réponses: 4
    Dernier message: 30/01/2005, 14h23
  3. [D7] Tableaux dynamiques dans un record
    Par bobby-b dans le forum Langage
    Réponses: 2
    Dernier message: 30/06/2004, 23h23
  4. Article sur les tableaux dynamiques
    Par Eric Sigoillot dans le forum Langage
    Réponses: 2
    Dernier message: 16/04/2004, 22h00
  5. [Kylix] Tableaux dynamiques sour Kylix2
    Par Krän dans le forum EDI
    Réponses: 6
    Dernier message: 07/10/2003, 14h31

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