1
votes

Dans Oracle APEX, je ne peux pas ajouter de données de plus de 32 Ko dans CLOB

J'ai du texte stocké dans une table de base de données, de nombreuses lignes courtes sur des champs de 70 à 90 caractères. (de raisons historiques). Je veux ajouter ces champs (lignes) dans un CLOB dans un APEX (CKEditor) et il dépasse 32k dans de nombreux cas. J'ai essayé de nombreuses façons, mais cela semble être une limite. Mon code fonctionne bien tant que le texte est inférieur à 32k! Mon plan est de le sauvegarder dans une nouvelle table et d'y utiliser un clob à la place. J'ai APEX 5.01. J'obtiens 'ORA-06502: PL / SQL: erreur numérique ou de valeur' ​​lorsqu'il est supérieur à 32 Ko.

declare
  l_clob     CLOB;
  l_seq      number;
  cursor textrader_cur is
  SELECT F1NR,FHTTYP,RADNR,FHTEXT,DATUM,UPPTAGEN,NUSER FROM DATATXT WHERE  DATATXT.F1NR = :P10_F1NR ORDER BY F1NR,FHTTYP,RADNR;
  TYPE datatext_typ IS TABLE OF DATATXT%ROWTYPE INDEX BY PLS_INTEGER;
  l_datatext  datatext_typ;

begin
  l_clob := empty_clob();
  DBMS_LOB.CREATETEMPORARY(l_clob,true);

  apex_collection.create_or_truncate_collection(p_collection_name => 'TEXT');

  select count(1) into x from DATATXT@HUMANAUTV WHERE DATATXT.F1NR = :P10_F1NR;
  if x > 0 then
    open textrader_cur;
    loop
      fetch textrader_cur bulk collect into l_datatext LIMIT 200;
      for indx in 1..l_datatext.COUNT loop
        y := length(l_datatext(indx).fhtext);
        dbms_lob.writeappend (l_clob,y,l_datatext(indx).fhtext);
        --l_clob := l_clob || l_datatext(indx).fhtext; -- This causes same error
      end loop;
      EXIT WHEN l_datatext.COUNT = 0; 
    end loop;
    close textrader_cur;

    l_seq := apex_collection.add_member(p_collection_name => 'TEXT',
       p_d001            => sysdate,
       p_d002            => sysdate,
       p_n001            => dbms_lob.getlength(l_clob),
       p_clob001         => l_clob);  

    -- :P10_WP       := l_clob;
    SELECT clob001 into :P10_WP FROM APEX_COLLECTIONS WHERE SEQ_ID = l_seq     AND COLLECTION_NAME='TEXT';   
  end if;
end;


0 commentaires

3 Réponses :


1
votes

Le problème est la dernière ligne de votre code. Les variables d'état de session (par exemple P10_WP ) sont toutes VARCHAR2 et limitées à 32767 caractères. Vous pouvez le voir dans les fonctions APEX qui les appellent ( exemple ). Ainsi, vous ne pouvez pas attribuer plus de 32 000 caractères à un élément de page PL / SQL .

Mais évidemment, vous pouvez mettre plus de 32k caractères dans un élément de formulaire HTML! C'est donc une solution de contournement délicate - vous devez obtenir les données clob dans et hors de l'élément de formulaire HTML sans utiliser les éléments de page APEX. En règle générale, cela se fait en écrivant le clob dans une collection, puis en utilisant des appels AJAX à un processus d'application pour le récupérer, car JavaScript n'a aucun problème avec les limites de caractères.

Il semble que vous y êtes arrivé le vôtre, avec votre collection TEXT , mais vous devrez toujours écrire votre propre processus d'application à la demande afin de pouvoir charger la collection dans JavaScript et la placer dans l'élément de formulaire HTML à partir de là. Ce sera plus facile si vous utilisez la fonctionnalité intégrée apex.ajax.clob avec la collection CLOB_CONTENT .

J'ai parcouru quelques articles à ce sujet, et celui-ci est plutôt bien écrit et simple .

La version courte consiste à changer le nom de votre collection dans votre code en CLOB_CONTENT , puis à mettre cette fonction JavaScript sur votre page et à l'appeler.

function clob_get(){
        var clob_ob = new apex.ajax.clob(
            function(){
                var rs = p.readyState
                if(rs == 1||rs == 2||rs == 3){
                    $x_Show('AjaxLoading');
                }else if(rs == 4){
                    $s('P10_WP',p.responseText);
                    $x_Hide('AjaxLoading');
                }else{return false;}
            }
        );
        clob_ob._get();
    }


2 commentaires

Non ce n'est pas dans la dernière ligne, le: P10_WP est un éditeur de texte enrichi (clob). Si je mets une remarque sur l'affectation de: P10_WP, j'obtiens toujours la même erreur. Si je mets une remarque sur «db, s_lob.writeappend», aucune erreur. Si je limite la boucle, il n'y aura donc aucune erreur <32k. J'ai également essayé (à des fins de test) de remplir le clob à presque 32k, puis d'utiliser 'dbms_lob.append (L_clob, l_clob)', mais cela génère également la même erreur. Si je lis un clob de la base de données dans la collection et que je l'assigne ensuite au: P10_WP, cela fonctionne très bien. Mais mes données sont présentées dans de nombreuses lignes de données char et je veux qu'elles soient concaténées en un clob!


Je pense que votre exemple javaScript est correct mais le problème est de remplir mon clob à partir de la table de base de données et non d'attribuer l'élément de formulaire



0
votes

PL / SQL dans APEX est limité à 32k, pl / sql traite les clobs comme varchar et c'est tout. Mon problème ne peut pas être résolu dans APEX


0 commentaires

1
votes

PL / SQL fournit un package dbms_lob pour manipuler ce type de données. La façon dont j'avais abordé un problème similaire avec une technologie différente (zope / python) était de créer un framework: Pour lire à partir de la base de données, il a renvoyé les données sous forme de lignes multipe Pour écrire dans db, il enverrait des données sous forme d'appels multipels et le serveur les combinait éventuellement.

Vous pouvez le voir ici Blob Journey de la base de données au navigateur


0 commentaires