Сохранение и извлечение данных CLOB размером более 32K в Oracle Apex



Моя цель-извлечь данные CLOB из базы данных в текстовую область в приложении Oracle Apex, а затем сохранить их в базе данных из самой текстовой области, нажав кнопку "Сохранить". У меня также есть некоторые другие поля на этой странице (как текстовые поля), которые не являются CLOB полями, и они должны быть сохранены в базе данных, а также при нажатии на кнопку.



Для этого я использую следующий код в разделе "HTML Header and Body Attribute" страницы. Это используется для извлечения / сохранения Клоб в текстовую область / базу данных. Обратите внимание, что простого кода PLSQL внутри элемента Apex будет достаточно, чтобы сделать то, что я делаю здесь, но только если данные CLOB меньше 32k байт. Я использую эту функцию из-за ограничения 32k в plsql в apex (и ограничения 4k, когда используется sql).



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" как 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 и non-CLOB в базу данных. Но как только страница отправляется, я получаю "http Bad Request".



Может ли кто-нибудь объяснить, почему это происходит и как я могу это решить?
803   1  

1 ответ:

Это код для apex.Аякс.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, вызовите clob_set с набором pSubmit:

clob_set(true);

Взгляните на вершину .отправить описание api . Также поймите, как работает кнопка: она отправляет страницу и устанавливает запрос на имя этого кнопка (или другое значение запроса, если оно определено явно).

Например, кнопка может быть названа "APPLY_CHANGES" и иметь метку "Change". Это важно, если вы используете, например, встроенную обработку строк. Значение запроса определяет, какое SQL-действие будет вызвано, и вы можете просмотреть возможные значения в деталях процесса, рядом с флажками для вставки/обновления/удаления.

Вот самая полезная красивая блок-схема:

схема clob_set

Comments

    Ничего не найдено.