Сохранение и извлечение данных 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".
Может ли кто-нибудь объяснить, почему это происходит и как я могу это решить?
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-действие будет вызвано, и вы можете просмотреть возможные значения в деталях процесса, рядом с флажками для вставки/обновления/удаления.
Вот самая полезная красивая блок-схема:

Comments