5

我的目标是将 CLOB 数据从数据库中检索到 Oracle Apex 应用程序中的 textarea 中,然后在按下“保存”按钮时将其从 textarea 本身保存到数据库中。我在此页面上还有一些其他字段(作为文本字段),它们是非 CLOB 字段,并且在单击按钮时也需要将它们保存在数据库中。

为此,我在页面的“HTML Header and Body Attribute”下使用了以下代码。这用于将 CLOB 检索/保存到 textarea/database 中。请注意,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();  
    }

我将“页面 HTML 正文属性”下的函数之一称为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;

这工作得很好。现在,我有一个 plsql 进程,它将在 CLOB 和非 CLOB 字段中输入的详细信息保存到数据库中。但是一旦页面提交,我就会收到“HTTP Bad Request”。

谁能解释为什么会发生这种情况,我该如何解决?

4

1 回答 1

1

这是 apex.ajax.clob 的代码,取自 apex_4_1.js:

/**
 * @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 字段替换为会话。创建一个执行 javascript 的动态操作,使用 pSubmit 集调用 clob_set:

clob_set(true);

请查看apex.submit api 描述。还要了解按钮的工作原理:它提交页面并将请求设置为该按钮的名称(或其他请求值,如果明确定义)。

例如,一个按钮可以命名为“APPLY_CHANGES”并具有标签“更改”。如果您使用例如内置的行处理,这很重要。请求值将确定将调用哪个 SQL 操作,您可以在插入/更新/删除复选框旁边的流程详细信息中查看可能的值。

在这里,一个最有用的漂亮流程图:

clob_set 流程图

于 2012-07-11T13:48:42.960 回答