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

SQL Firebird Discussion :

[blob et procédure stockée]


Sujet :

SQL Firebird

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 379
    Par défaut [blob et procédure stockée]
    Hello à tous,

    pour des raisons de performance, j'ai besoin d'assembler environ 1 milliers d'enregistrements d'environ 60 caractères en une seule chaîne.

    le problème est que les procédures stockées ne peuvent dépasser plus de 32765 caractères en retour.

    l'idée est donc d'utiliser un blob en réponse, mais là j'ai un code d'erreur "internal error"
    j'ai trouvé des milliers de réponses traitant sur les blobs et les procédures stockées, mais aucune qui me vient en aide.

    je sais que le blob n'est qu'une référence dans la table et que cette référence "pointe" d'une manière ou d'une autre dans le fichier de la base de données. il y a donc dans ce cas ci un problème de ressource, puis la variable "blob" ne référence pas un champ, mais devrait représenter le contenu.

    pour mieux comprendre la chose, voici un exemple de code:
    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
    CREATE PROCEDURE GetBlob( Reference INTEGER )
    RETURNS( LaGrandeReponse BLOB )
    AS
      DECLARE VARIABLE INFO Varchar( 50 );
    BEGIN
     
      LaGrandeReponse = '';
     
      FOR SELECT Info FROM MaTable WHERE Reference = :Reference
      INTO :INFO DO
        LaGrandeReponse = LaGrandeReponse || INFO;
     
      SUSPEND;
     
    END
    pour obtenir les infos: SELECT LaGrandeReponse FROM GetBlob( 1234 )

    je me doute que ce code est insuffisant! d'où ma demande d'aide

    il y a certainement une histoire de curseur ou autre, mais j'avoue ne jamais avoir utiliser une telle chose

    des idées, des suggestions, merci d'avance?

  2. #2
    Membre chevronné Avatar de JustMe
    Inscrit en
    Juillet 2002
    Messages
    479
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 479
    Par défaut
    N'est-il pas necessaire de mentionner le sous type du blob et la taille du segment?

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 379
    Par défaut
    si, mais dans ce cas, cela ne change rien! j'ai essayé, tu pense!

    dans l'interval, j'ai peux-être trouvé une solution, mais elle passe par une udf, chose que je voulais évité si possible, mais faute de solution, je passerais par ça.

  4. #4
    Membre chevronné Avatar de JustMe
    Inscrit en
    Juillet 2002
    Messages
    479
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 479
    Par défaut
    Je pense que la concaténation d'un blob n'est pas permise d'ou le message d'une erreur interne.

  5. #5
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 379
    Par défaut
    de fait, il n'est pas possible de concaténer des blobs, ce n'est d'ailleurs pas le but du jeu, le but étant d'assembler un volume relativement important de chaînes environ 65Ko et de retourner le tout dans une seule requête.

    d'ou l'idée d'utiliser un blob plutôt qu'un varchar qui limite le volume à 32765 caractères dans une seule requête.

    merci de tes idées

  6. #6
    Membre Expert

    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2004
    Messages
    2 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 123
    Par défaut
    Salut,

    Je n'ai peut être pas tout compris mais je me pose quelques questions...

    Le fait de rapatrier une très longue chaine de caractère risque d'être couteux en ressource :
    exemple
    La requete retourne une chaine de 1 Mo. Si lors de ce retour, il y a dégradation des données (erreur réseaux etc...), le résultat sera alors de nouveau renvoyer en un block. Bilan 2 Mo sont passés.
    Ce qui fait qu'en cas d'erreur, le traffic réseau risque de s'encombrer rapidement, etc ...
    Enfin c'est ce qu'il me semble...

    Pourquoi ne pas lancer cette requete sur un poste client ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Info FROM MaTable WHERE Reference = :Reference
    Et par la suite, faire la concaténation sur ce poste ?

    Cela allège les taches du serveur et utilise les performances du poste client qui est généralement moins solicité.

    Mais bon, je pense que tu y avais déjà pensé. Je suis peut être passé à coté de quelque chose ?

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 379
    Par défaut
    effectivement le volume et très important!

    pour dire, ce sont des extractions de données et les fichiers produits atteignes facilement le giga, alors 1 ou 2 mégas de plus ne change rien.

    ce qui change, c'est la performace!

    depuis le début de ce post, j'ai appliqué sur ce que je pouvais le retour de données de 3 tables via 3 procédures stockées (une par table et le retour en varchar) et grace à cela, je suis passé d'une extraction qui tournait au alentour de 3 enregistrements secondes à 400 enregistrements secondes!

    simplement, les procédures mettent en ligne les données qui sont habituellement extraites depuis l'intérieure d'une "grande" boucle via de "petites" boucles

    mais il me reste une table qui peut retourner plus de 1100 enregistrements d'environ 50 à 60 caractères et là, avec les 3 autres procédures je suis coincé, car la somme des 3 autres procédures atteint la limite fatidique des 32765 caractères et donc pouic...

    de plus, effectuer la jointure avec toutes les tables et produire un "monstreux" résultat dénormalisant les tables, puis utiliser une boucle à rupture de séquence sera infiniment contre producteur, sans compter le volume exorbitant produit par une telle jointure, d'où l'idée d'utilser des procédures stockées pour mettre en un seul enregistrement des centaines d'enregistrements d'une (sous-table-détail) et de retourner le tout dans la requête de la "grande" boucle qui devient alors l'unique requête.

    en résumé c'est juste une question de performance, pas de simplifier quelque chose qui à la base est déjà complexe (et c'est un doux euphemisme) (nombreux formats d'exportations, plusieurs bases de données et plusieurs dizaines de tables)

    c'est pour cela que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT Info FROM MaTable WHERE Reference = :Reference
    qui était déjà en utilisation (les petites boucles) ralentissent considérablement l'exportation à cause des ouvertures et fermetures répétées des requêtes (préparées tout de même!)

    voilà, le pourquoi.

    merci de t'y intéresser

  8. #8
    Membre Expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 052
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 052
    Par défaut
    Bonjour,

    Il me semble que l'on ne peut mannipuler le contenu des blob dans une PS ou Trigger. (D'ou l'erreur)

    L'utilisation des blobs dans les PS se limite donc à de la sélection comme si c'était un tout.

    Une des solutions que j'essayerai c'est de développer une UDF pour créer ce blob (en m'aidant du code source de la fonction B_Put_Segment de l'UDF RFUNC). Soit cette UDF manipulerait le Blob pour lui ajouter une chaine en fin soit elle ferait elle même l'extraction (le select) et en retour il y aurait un Blob.

    Si celà ne marche pas c'est peut etre qu'on ne peux pas créer de Blob dynamiquement (mais je ne pense pas) dans ce cas une autre solution qui aurait plus de chance de fonctionner mais qui serait moins performante c'est d'avoir une table avec une colonne Blob et un identifiant. La fonction (UDF) créerait ou alimenterait le blob dans cette table et retournerait l'identifiant du blob (dans le cas de la création) que la PS pourrait lire pour retourner le résultat. Mais est ce bien raisonnable de faire ca si la chaine ne fait que 65Ko max ? (et donc le seul but de la mannip serait d'éviter d'avoir deux/trois enregistrements de 32Ko en retour à la place d'un enregistrement avec un Blob)

    Sinon je ne connais pas le contexte (concurence du traitement ou non ?) mais pourquoi ne pas créer une fichier externe (avec un nom unique) avec le résultat de la concaténation des chaines dans un répertoire partagé. La PS renverait le nom du fichier. Le poste client pouvant ainsi le lire entièrement ou partiellement suivant le besoin et le détruire ou archiver après utilisation.

  9. #9
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 379
    Par défaut
    yo! merci barbibulle de tes lumières

    la solution UDF est celle que j'envisagé dès le début, mais je voulais l'évité si cela était possible.

    la construction d'une table "blob" est trop lent, j'ai essayé, beaucoup de travail, pour très peu de résultats.

    je penche donc pour l'udf et merci pour le tuyeau b_put_segment

    à ce niveau je dirais que le problème et donc résolu, merci à tous

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 04/12/2012, 16h42
  2. [Pl/Sql] blob et une procédure stockée
    Par choubiroute dans le forum Oracle
    Réponses: 5
    Dernier message: 15/03/2006, 11h07
  3. [Oracle] Insertion d'un blob en passant par une procédure stockée
    Par choubiroute dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 10/03/2006, 18h34
  4. Explication procédure stockée
    Par underworld dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 09/09/2002, 10h51
  5. [Comparatif] Procédures stockées, triggers, etc.
    Par MCZz dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 28/08/2002, 12h27

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