Précédent   Forum des professionnels en informatique > Bases de données > Firebird > SQL
SQL Forum d'entraide sur le SQL pour Firebird
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 07/04/2005, 17h56   #1
Membre éclairé
 
Inscription : décembre 2004
Messages : 379
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 379
Points : 304
Points : 304
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 :
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?
jean-jacques varvenne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/04/2005, 10h21   #2
Membre éprouvé
 
Avatar de JustMe
 
Inscription : juillet 2002
Messages : 432
Détails du profil
Informations forums :
Inscription : juillet 2002
Messages : 432
Points : 441
Points : 441
N'est-il pas necessaire de mentionner le sous type du blob et la taille du segment?
__________________
<On fait la science avec des faits, comme on fait une maison avec des pierres : mais une accumulation de faits n'est pas plus une science qu'un tas de pierres n'est une maison> **Poincaré**
http://www.mobile-tactile.com/
JustMe est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/04/2005, 09h08   #3
Membre éclairé
 
Inscription : décembre 2004
Messages : 379
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 379
Points : 304
Points : 304
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.
jean-jacques varvenne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/04/2005, 09h38   #4
Membre éprouvé
 
Avatar de JustMe
 
Inscription : juillet 2002
Messages : 432
Détails du profil
Informations forums :
Inscription : juillet 2002
Messages : 432
Points : 441
Points : 441
Je pense que la concaténation d'un blob n'est pas permise d'ou le message d'une erreur interne.
__________________
<On fait la science avec des faits, comme on fait une maison avec des pierres : mais une accumulation de faits n'est pas plus une science qu'un tas de pierres n'est une maison> **Poincaré**
http://www.mobile-tactile.com/
JustMe est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2005, 13h42   #5
Membre éclairé
 
Inscription : décembre 2004
Messages : 379
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 379
Points : 304
Points : 304
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
jean-jacques varvenne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2005, 08h40   #6
Rédacteur
 
Inscription : janvier 2004
Messages : 2 123
Détails du profil
Informations personnelles :
Âge : 31

Informations forums :
Inscription : janvier 2004
Messages : 2 123
Points : 1 977
Points : 1 977
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 :
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 ?
__________________
Ancien pseudo : yobenzen

Recherche un emploi de Chef de Projet ou Développeur en Normandie
Delphi/Oracle/Interbase
Migration vers symfony

CV :
- LinkedIn
- Viadeo
Benjamin GAGNEUX est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2005, 10h22   #7
Membre éclairé
 
Inscription : décembre 2004
Messages : 379
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 379
Points : 304
Points : 304
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 :
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
jean-jacques varvenne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2005, 11h52   #8
Membre Expert
 
Avatar de Barbibulle
 
Frédéric
Inscription : octobre 2002
Messages : 1 722
Détails du profil
Informations personnelles :
Nom : Frédéric
Âge : 42

Informations forums :
Inscription : octobre 2002
Messages : 1 722
Points : 2 025
Points : 2 025
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.
Barbibulle est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2005, 14h33   #9
Membre éclairé
 
Inscription : décembre 2004
Messages : 379
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 379
Points : 304
Points : 304
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
jean-jacques varvenne est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h41.


 
 
 
 
Partenaires

Hébergement Web