5

私の目的は、CLOB データをデータベースから Oracle Apex アプリケーションのテキストエリアに取得し、[保存] ボタンを押すとテキストエリア自体からデータベースに保存できるようにすることです。このページには、CLOB フィールド以外の他のフィールド (テキストフィールドとして) もあり、ボタンをクリックしたときにデータベースにも保存する必要があります。

このために、ページの「HTML ヘッダーと本文の属性」の下に次のコードを使用しています。これは、CLOB をテキストエリア/データベースに取得/保存するために使用されます。Apex アイテム内の単純な PLSQL コードは、ここで行っていることを実行するのに十分ですが、CLOB データが 32k バイト未満の場合のみです。この関数を使用しているのは、apex の plsql の 32k 制限 (および sql を使用する場合の 4k 制限) のためです。

function clob_set(){  
        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('P5075_RESPONSETEXT',p.responseText);  
                    $x_Hide('AjaxLoading');  
                }else{return false;}  
            }  
        );  

        if(!$v_IsEmpty('P5075_STYLESHEET')){clob_ob._set($v('P5075_STYLESHEET'))};  
    }  

    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('P5075_STYLESHEET',p.responseText);  
                    $x_Hide('AjaxLoading');  
                }else{return false;}  
            }  
        );  
        clob_ob._get();  
    }

"Page HTML Body Attribute" の下にある関数の 1 つをonload = "javascript:clob_get();"として呼び出しています。

これにはヘッダー処理後の PLSQL があります。

declare
l_clob clob:= empty_clob();

begin

if apex_collection.collection_exists(p_collection_name=>'CLOB_CONTENT') then
apex_collection.delete_collection(p_collection_name=>'CLOB_CONTENT');
end if;

apex_collection.create_or_truncate_collection(p_collection_name=>'CLOB_CONTENT');
dbms_lob.createtemporary( l_clob, false, dbms_lob.SESSION );

SELECT xslt
INTO l_clob
FROM schematransform
WHERE namn = 'f';

apex_collection.add_member(p_collection_name => 'CLOB_CONTENT',p_clob001 => l_clob);
end;

これはうまく機能しています。現在、CLOB および非 CLOB フィールドに入力された詳細をデータベースに保存する plsql プロセスがあります。しかし、ページが送信されるとすぐに、「HTTP Bad Request」が表示されます。

なぜこれが起こっているのか、どうすれば解決できるのか、誰か説明してもらえますか?

4

1 に答える 1

1

これは、apex_4_1.js から取得した apex.ajax.clob のコードです。

/**
 * @namespace = apex.ajax
 */
apex.ajax = {
    /*clob*/
    clob : function (pReturn){
        var that = this;
        this.ajax = new htmldb_Get(null,$x('pFlowId').value,'APXWGT',0);
        this.ajax.addParam('p_widget_name','apex_utility');
        this.ajax.addParam('x04','CLOB_CONTENT');
        this._get = _get;
        this._set = _set;
        this._return = !!pReturn?pReturn:_return;
        return;
        function _get(pValue){
            that.ajax.addParam('x05','GET');
            that.ajax.GetAsync(that._return);
        }
        function _set(pValue){
            that.ajax.addParam('x05','SET');
            that.ajax.AddArrayClob(pValue,1);
            that.ajax.GetAsync(that._return);
        }
        function _return(){
        if(p.readyState == 1){
            }else if(p.readyState == 2){
            }else if(p.readyState == 3){
            }else if(p.readyState == 4){
              return p;
            }else{return false;}
        }
    },

したがって、clob の設定と取得は完全に非同期です。投稿したコードは、リクエストが終了したときに呼び出される処理関数を提供します(htmldb_getで行われます)。それは醜い回避策だと思いますが、大丈夫です。サブミットを機能させるには、この関数コードを操作する必要があります。セットは非同期であるため、セットが発生する前にページが送信されないという保証はありません。これを防ぐには、 clob_set コードを次のように修正します。

function clob_set(pSubmit){
   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){
             //here the clob has actually been saved, and
             // the ajax call finished
            $s('P5075_RESPONSETEXT',p.responseText);
            $x_Hide('AjaxLoading');

            //pSubmit is a new param
            //use it to check if set has been called for
            //a page submit or not
            if(pSubmit){
               //disable the clob field: it should not be
               //substituted to the session state!!
               $('#P5075_STYLESHEET').prop("disabled", true);
               //actually submit the page. This will submit
               //all fields to session except the disabled ones
               apex.submit('SUBMIT');
            };
         }else{
            return false;
         };
      });

   if(!$v_IsEmpty('P5075_STYLESHEET')){
      clob_ob._set($v('P5075_STYLESHEET'));
   };
};

送信ボタンを変更し、そのアクションを動的アクションで定義します。これを行う必要があるのは、デフォルト プロセスによって clob-field がセッションに置き換えられるのを防ぐためです。javascript を実行する動的アクションを作成し、 pSubmit を設定して clob_set を呼び出します。

clob_set(true);

apex.submit api descriptionを見てください。また、ボタンがどのように機能するかを理解してください。ボタンはページを送信し、リクエストをそのボタンの名前 (または明示的に定義されている場合は別のリクエスト値) に設定します。

たとえば、ボタンに「APPLY_CHANGES」という名前を付け、「Change」というラベルを付けることができます。これは、組み込みの行処理などを使用する場合に重要です。要求値によって、どの SQL アクションが呼び出されるかが決まります。挿入/更新/削除のチェックボックスの横にあるプロセスの詳細で、可能な値を確認できます。

ここに、最も役立つ美しいフローチャートがあります。

clob_set フローチャート

于 2012-07-11T13:48:42.960 に答える