Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
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 13/05/2011, 21h49   #1
Membre à l'essai
 
Inscription : octobre 2008
Messages : 86
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 86
Points : 24
Points : 24
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 :
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 :
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 !
Jonathan.Harvey est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 09h24   #2
Membre chevronné
 
Homme O. Joly
Support
Inscription : décembre 2010
Messages : 287
Détails du profil
Informations personnelles :
Nom : Homme O. Joly
Âge : 38
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : Support
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : décembre 2010
Messages : 287
Points : 617
Points : 617
Je suis en version 11gR2

Code :
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 ...
ojo77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 18h43   #3
Membre à l'essai
 
Inscription : octobre 2008
Messages : 86
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 86
Points : 24
Points : 24
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 :
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 :
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.
Jonathan.Harvey est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 19h37   #4
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 438
Points : 10 438
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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.
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 19h41   #5
Membre à l'essai
 
Inscription : octobre 2008
Messages : 86
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 86
Points : 24
Points : 24
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
Jonathan.Harvey est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 19h45   #6
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 438
Points : 10 438
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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 !
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 19h57   #7
Membre à l'essai
 
Inscription : octobre 2008
Messages : 86
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 86
Points : 24
Points : 24
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 :
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 :
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 :
1
2
INSERT maFonction('toto')
INTO MaTableB;
Ne soit pas simplement interpréter comme
Code :
1
2
INSERT 'toto2'
INTO MaTableB
** en supposant que maFonction ajoute la valeur 2 à un champs passé en paramètre **
Jonathan.Harvey est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 20h16   #8
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 438
Points : 10 438
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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 :
1
2
3
INSERT INTO MaTableB (ma_col_varchar)
SELECT maFonction(ma_col_clob)
  FROM MaTableA;
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 20h17   #9
Membre à l'essai
 
Inscription : octobre 2008
Messages : 86
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 86
Points : 24
Points : 24
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.
Jonathan.Harvey 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 13h24.


 
 
 
 
Partenaires

Hébergement Web