Sno*_*ard 5 plsql clob onload oracle-apex
我的目标是将数据库中的 CLOB 数据检索到 Oracle Apex 应用程序中的文本区域,然后能够在按下“保存”按钮时将其从文本区域本身保存到数据库中。我在此页面上还有一些其他字段(作为文本字段),它们是非 CLOB 字段,它们也需要在单击按钮时保存在数据库中。
为此,我在页面的“HTML Header and Body Attribute”下使用以下代码。这用于将 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();
}
Run Code Online (Sandbox Code Playgroud)
我将“页面 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;
Run Code Online (Sandbox Code Playgroud)
这工作得很好。现在,我有一个 plsql 进程,它将在 CLOB 和非 CLOB 字段中输入的详细信息保存到数据库中。但是一旦页面提交,我就会收到“HTTP 错误请求”。
任何人都可以解释为什么会发生这种情况,我该如何解决?
这是 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;}
}
},
Run Code Online (Sandbox Code Playgroud)
因此,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'));
};
};
Run Code Online (Sandbox Code Playgroud)
更改您的提交按钮,并通过动态操作定义其操作。您需要执行此操作以防止通过默认过程将 clob 字段替换到会话中。创建一个执行 javascript 的动态操作,调用 clob_set 并设置 pSubmit:
clob_set(true);
Run Code Online (Sandbox Code Playgroud)
请查看apex.submit api 说明。还要了解按钮的工作原理:它提交页面并将请求设置为该按钮的名称(或另一个请求值,如果明确定义)。
例如,按钮可以命名为“APPLY_CHANGES”并具有标签“Change”。例如,如果您使用内置行处理,这一点很重要。请求值将确定将调用哪个 SQL 操作,您可以在插入/更新/删除复选框旁边的流程详细信息中查看可能的值。
这是一个最有用的漂亮流程图:
