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 :

Appel fonction avec plus de 4000 bytes.


Sujet :

PL/SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Octobre 2008
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 86
    Points : 55
    Points
    55
    Par défaut Appel fonction avec plus de 4000 bytes.
    Bonjour,

    J'essai en vain de trouver une façon d'appeler une fonction en lui passant plus de 4000 bytes.

    Ma fonction est, on ne peux plus simple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    create or replace function fctSimple(v_lob clob) return clob is
         Result clob;
    begin
      Result := 'toto';
      return(Result);
     
    end fctSimple;
    et mon appel, tout aussi simple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Declare
       v_tmp varchar2(2000);
    Begin
     
       v_tmp := fctSimple('** CHAINE D'UNE LONGUEUR DE 4200 bytes **');
    End;
    Et j'ai droit à cet erreur : ORA-01704 : constante de chaîne trop longue.

    Si je met 3999 byte, sa passe.

    J'ai essayer avec clob, long, blob.... À chaque fois la même erreur ORA.

    Ma question est fort simple ( ou pas ) :
    Existe-il une façon d'appeler une fonction Oracle en lui passant comme paramètre une chaine de plus de 4000 caractères.

    En vous remerciant !

  2. #2
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Je suis en version 11gR2

    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
    SQL> desc big_table
     Nom                                       NULL ?   Type
     ----------------------------------------- -------- ----------------------------
     C1                                                 NUMBER
     C2                                                 NUMBER
     C3                                                 VARCHAR2(10)
     C4                                                 DATE
     
    SQL> select avg(length(c3)), count(*) from big_table;
     
    AVG(LENGTH(C3))   COUNT(*)
    --------------- ----------
                 10   10000000
     
    SQL> create or replace function tst_fs return clob is
      2   ttext varchar2(32767);
      3   cl_txt clob;
      4  begin
      5  cl_txt:='debut';
      6  for i in (select * from big_table where rownum < 410)
      7  loop
      8      ttext := i.c3;
      9      dbms_lob.writeappend(cl_txt,length(ttext),ttext);
     10  end loop;
     11  return fctSimple(cl_txt);
     12  end;
     13  /
     
    Fonction crÚÚe.
     
     
    SQL>
    SQL> set timi on
    SQL> select tst_fs() from dual;
     
    TST_FS()
    --------------------------------------------------------------------------------
    toto
     
    EcoulÚ : 00 :00 :00.51
    Ca fonctionne, c'est testé avec 4095 caractères ...

  3. #3
    Membre du Club
    Inscrit en
    Octobre 2008
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 86
    Points : 55
    Points
    55
    Par défaut
    En faite, je me rend compte que mon problème est différent que la façon dont je l'ai présenté.

    C'est dans un INSERT INTO ... que j'ai ce problème sauf si je passe par une variable.


    Donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Declare
       v_tmp varchar2(2000);
    Begin
     
       v_tmp := fctSimple('** CHAINE D'UNE LONGUEUR DE 6000 byte et qui retourne 4000 bytes **');
     
      INSERT INTO maTable_a_une_colonne(maColonne)
      VALUES(v_tmp);
    End;
    Fonctionne ! et sa insere exactement les 4000 bytes .

    MAIS.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Declare
     
    Begin
     
      INSERT INTO maTable_a_une_colonne(maColonne)
      VALUES(fctSimple('** CHAINE D'UNE LONGUEUR DE 6000 byte et qui retourne 4000 bytes **'););
    End;
    Me retourne l'erreur ORA-01704 : constante de chaîne trop longue.


    Des idées ?

    Dans le fond, sa revient au même que de faire un
    select 'CHAINE DE 6000 byte'
    from dual;

    Sa donne la même erreur.

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    En SQL la précision maximale d'un varchar est de 4000, en PL/SQL c'est 32767.

    Dans votre premier cas de figure vous êtes en PL/SQL, dans le second vous appliquez une instruction purement SQL.

  5. #5
    Membre du Club
    Inscrit en
    Octobre 2008
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 86
    Points : 55
    Points
    55
    Par défaut
    En effet, c'est pour sa que mon exemple du début n'était pas représentatif de mon problème.

    Mon problème est donc d'arriver à passer en paramètre une chaine de plus de 4000 bytes..

    C'est dommage parce que ma fonction fctSimple()... retourne quand à elle toujours moins de 4000 bytes.

    Sur ora-code, l'explication de mon erreur ORA est assez clair.

    ORA-01704: string literal too long
    Cause: The string literal is longer than 4000 characters.

    C'est la limite des suggestions qui m'aides pas

    Use a string literal of at most 4000 characters. Longer values may only be entered using bind variables.

    Je ne veux / peux pas utiliser de bind variables

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Essayez de décrire un peu le pourquoi du comment afin de voir si votre problème ne peut pas être appréhendé différemment !

  7. #7
    Membre du Club
    Inscrit en
    Octobre 2008
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 86
    Points : 55
    Points
    55
    Par défaut
    J'ai un champ dans un clob, de grandeur 0 ( null ) à environs 7000 bytes.


    Ma fonction fait entre-autre comme traitement retirer des bouts ainsi que d'autres traitement divers.


    Le contenu passe de la table A ( contenant le clob ) à la table B ( content un varchar2(4000) ) via un fichier sql ( appelons le, fichierC.sql )

    Actuellement les 2 champs sont des varchar2(4000), l'ajout du clob fait partit d'un grand changement dont je dois garder pour moi les détails.


    Donc, un script est lancé et crée des commandes d'insert dans le fichier fichierC.sql.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    INSERT ('toto')
    INTO MaTableB;
     
    INSERT ('baba')
    INTO MaTableB;
    De 1 à des milliers d'insertions.

    Ma modifications consiste donc à vouloir faire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    INSERT maFonction('toto')
    INTO MaTableB;
     
    INSERT maFonction('baba')
    INTO MaTableB;
    Sa fonctionne #1 , sauf quand le contenu de la string à plus de 4000 bytes.

    Mais comme je disait, le retour de la fonction n'a jamais plus de 4000 bytes !

    Je trouve sa dommage que le

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT maFonction('toto')
    INTO MaTableB;
    Ne soit pas simplement interpréter comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT 'toto2'
    INTO MaTableB
    ** en supposant que maFonction ajoute la valeur 2 à un champs passé en paramètre **

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Ok, c'est l'étape avec le script SQL qui pêche.

    Il n'y a pas moyen de l'écrire en une seule requête ensembliste, de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO MaTableB (ma_col_varchar)
    SELECT maFonction(ma_col_clob)
      FROM MaTableA;

  9. #9
    Membre du Club
    Inscrit en
    Octobre 2008
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 86
    Points : 55
    Points
    55
    Par défaut
    Non, parce que les 2 tables ne se voient pas.

    la TableB, ne peux pas voir la TableA.

    C'est pour sa qu'on passe par un fichier sql.

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

Discussions similaires

  1. Appel fonction avec des paramètres se trouvant dans des cellules
    Par SI-SHARE dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 24/04/2013, 10h02
  2. Appeler fonction avec paramètre
    Par Doom2Darkness dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 08/03/2009, 20h09
  3. [DOM] Appel fonction avec paramètre depuis document.write
    Par kev42100 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 06/05/2008, 14h12
  4. Appeler une fonction avec "action" ds un
    Par drinkmilk dans le forum ASP
    Réponses: 4
    Dernier message: 20/04/2004, 14h54
  5. Appeler une fonction avec/sans parenthèses
    Par haypo dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 29/12/2002, 18h48

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