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

PL/SQL Oracle Discussion :

Valeur de variable et fonction dbms_lob.getlength()


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Février 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 10
    Par défaut Valeur de variable et fonction dbms_lob.getlength()
    Bonjour à tous,

    Débutant en PL/SQL je me retrouve confronté un petit soucis technique. J'utilise dans une procédure stockée la ligne suivante :

    select (avg(nvl(dbms_lob.getlength(Current_Column_Name),0)+1))
    into Current_Size from archvector where rownum < 2 ;

    La valeur de Current_Column_Name est : IMAGE_DATA


    A priori ma variable Current_Column_Name est interprété comme une chaine de caractère car le résultat de la requête ci dessus dans ma procédure donne 11 ( le nombre de caractère de la string : IMAGE_DATA ) et non la taille de mon BLOB qui fait 16 Ko.

    J'ai essayé un peu tout les operateurs et j'ai cherché sur le net un peu partout mais difficile de décrire mon problème.

    Savez-vous s'il y'a un operateur ou une fonction qui permet de faire ce que je veux faire ? ( j'ai essayé &Current_Column_Name , /Current_Column_Name et ce genre de chose mais ça ne fonctionne pas)

    Merci d'avance ,

    ++

    ArchVector

  2. #2
    Membre chevronné Avatar de xdescamp
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 300
    Par défaut
    Bonjour,

    Il faudrait avoir un peu plus d'infos sur ton script et sur ce que tu cherches à faire exactement.
    Si ce que tu veux est pouvoir changer le nom de la colonne lorsque ton script est lancé sous SQL*Plus, il faut bien utiliser le & et passer le nom de la colonne sans cotes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SQL> desc xde
     Nom                                       NULL ?   Type
     ----------------------------------------- -------- ----------------------------
     ID                                                 NUMBER(38)
     IMAGE_DATA                                         BLOB
    
    SQL> select (avg(nvl(dbms_lob.getlength(&Current_Column_Name),0)+1)) from xde;
    Entrez une valeur pour current_column_name : image_data
    ancien   1 : select (avg(nvl(dbms_lob.getlength(&Current_Column_Name),0)+1)) from xde
    nouveau   1 : select (avg(nvl(dbms_lob.getlength(image_data),0)+1)) from xde
    
    (AVG(NVL(DBMS_LOB.GETLENGTH(IMAGE_DATA),0)+1))
    ----------------------------------------------
                                                 1
    Le résultat est ici 1 car ma table ne contient qu'un enregistrement avec un BLOB vide.

  3. #3
    Membre habitué
    Inscrit en
    Février 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 10
    Par défaut
    Salut Xdescamp,

    Merci pour ta réponse. J'essai de faire un script pour sizer la taille de ma DB (je ne peux pas utiliser le avg_row_length d'oracle10G car celui ci prend en compte tous les rows et moi je veux faire mon sizing à partir de records bien précis dans chaque table). On va dire que ce sera un sizing selectif.

    Voici mon script (c'est juste le début)

    DECLARE
    TYPE MyCursor IS REF CURSOR;
    Read_Table MyCursor;
    Current_Column_Name VARCHAR2(30);
    Current_Data_Type VARCHAR2(106);
    Current_Size INTEGER;
    Total_Size INTEGER:=3;


    BEGIN

    -- On ouvre le curseur
    OPEN Read_Table FOR
    select COLUMN_NAME, DATA_TYPE from DBA_TAB_COLUMNS where table_name='PICS';


    LOOP
    FETCH Read_Table INTO Current_Column_Name, Current_Data_Type;
    EXIT WHEN Read_Table%NOTFOUND;

    -- If it's a blob we use dbms_lob package
    IF (Current_Data_Type = 'BLOB')
    THEN
    DBMS_OUTPUT.PUT_LINE ('BLOB: ' || Current_Column_Name);
    select (avg(nvl(dbms_lob.getlength(Current_Column_Name),0)+1)) into Current_Size from PICS where rownum < 1000 and status='present';
    DBMS_OUTPUT.PUT_LINE ('Size : ' || Current_Size);
    ELSE
    -- If it's not a blob we use vsize function
    DBMS_OUTPUT.PUT_LINE ('OTHERS: ' || Current_Column_Name);
    select (avg(nvl(vsize(Current_Column_Name),0)+1)) into Current_Size from PICS where rownum < 1000 and status='present';
    DBMS_OUTPUT.PUT_LINE ('Size : ' || Current_Size);
    END IF;

    -- Total size incrementation
    Total_Size := Total_Size + Current_Size;

    DBMS_OUTPUT.PUT_LINE ('Taille totale :' || Total_Size );

    END LOOP;
    -- On ferme le curseur
    CLOSE Read_Table;

    END;
    /

    Je voudrais pouvoir cumuler la size de chaque colonne de chacune de mes tables mais dans la partie en gras, Current_Column_Name est interpété comme une chaine de caractère et non comme l'intitulé d'une colonne de type BLOB.

    Dans ma table PICS j'ai un BLOB et quelques colonnes VARCHAR32.

  4. #4
    Membre habitué
    Inscrit en
    Février 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 10
    Par défaut
    En fait quand je tappe la commande sous TOAD, ça fonctionne bien. Mais si je l'inclus dans ma procédure stockée ça ne marche pas.

    Je pense qu'il remplace :

    select (avg(nvl(dbms_lob.getlength(Current_Column_Name),0)+1)) into Current_Size from PICS where rownum < 1000 and status='present';

    par

    select (avg(nvl(dbms_lob.getlength("IMAGE_DATA"),0)+1)) into Current_Size from PICS where rownum < 1000 and status='present';

    au lieu de

    select (avg(nvl(dbms_lob.getlength(IMAGE_DATA),0)+1)) into Current_Size from PICS where rownum < 1000 and status='present';

  5. #5
    Membre chevronné Avatar de xdescamp
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 300
    Par défaut
    Dans ce cas, il faut que tu construises ta requête dans une chaine de caractères, puis que tu l'exécutes avec un EXECUTE IMMEDIATE:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    DECLARE
      ...
      V_Ordre_Sql VARCHAR2(4000);
      ...
    BEGIN
      ...
      V_Ordre_Sql := 'select (avg(nvl(dbms_lob.getlength(' || Current_Column_Name || '),0)+1)) into Current_Size from PICS where rownum < 1000 and status=''present''';
      EXECUTE IMMEDIATE V_Ordre_Sql INTO Current_Size;
      ...

  6. #6
    Membre habitué
    Inscrit en
    Février 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 10
    Par défaut
    Pas bête! je vais tester ça de suite.

    Mais en PL/SQL il n'y a pas de "symbole" pour éviter ce problème de passage de variable ? Est-ce qu'en général la construction de requête dans une variable avec execute immediate est quelque chose de commun ?

  7. #7
    Membre habitué
    Inscrit en
    Février 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 10
    Par défaut
    Ca marche jusqu'au Execute immediate ou la il me dit caractère invalide

    Je viens de regardé la syntaxe , à priori c'est du SQL dynamique, je sais pas si c'est compatible avec mon script car le reste est écrit en SQL "classique".

    Bref, je vais voir si c'est pas un problème de type de variable avec le INTO.


    Edit : en fait c'était le ; à la fin de la requête SQL que le execute immediate n'aimait pas !

    Ca marche bien désormais,

    Merci !

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

Discussions similaires

  1. [XL-2010] Attribuer une valeur à une variable en fonction d'une autre
    Par jkiii dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 13/11/2013, 19h17
  2. Réponses: 2
    Dernier message: 20/08/2013, 16h38
  3. Variable qui change de valeur à chaque appel de fonction
    Par bpascal123 dans le forum Débuter
    Réponses: 5
    Dernier message: 12/03/2010, 11h47
  4. Réponses: 7
    Dernier message: 14/05/2009, 16h22
  5. Variables qui perdent leur valeur lorsqu'utilisées dans fonction
    Par damlarumeur dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/02/2009, 09h05

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