我们已经使用了这个程序(借用),它已经工作得很好。
create or replace function fn_dblink_clob(
p_dblink in varchar2
, v_remote_table in varchar2
, p_clob_col in varchar2
, p_rid in urowid
)
return clob is
/** A function to fetch a CLOB column over a dblink **/
/** Laurence Prescott 25-Aug-17 **/
/** select dblink_clob('some_dblink', 'some_clob_column', rowid)
from some_table@some_dblink;
Note: Does not work on tables that have a virtual column (eg. xmltype).
**/
c_chunk_size constant pls_integer := 4000;
v_chunk varchar2(5000);
v_clob clob;
v_pos pls_integer := 1;
begin
dbms_lob.createtemporary(v_clob, true, dbms_lob.call);
loop
execute immediate
'select dbms_lob.substr@' ||p_dblink|| '(' ||p_clob_col|| ', ' ||c_chunk_size
|| ', ' ||v_pos|| ') from ' ||v_remote_table|| '@' ||p_dblink|| ' where rowid = :rid '
into v_chunk using p_rid;
begin dbms_lob.append(v_clob, v_chunk);
exception when others then
if sqlcode = -6502 then exit; else raise; end if;
end;
if length(v_chunk) < c_chunk_size then exit; end if;
v_pos := v_pos + c_chunk_size;
end loop;
return v_clob;
end fn_dblink_clob;
我们通常将其指向一个物理表,但现在需要指向一个VIEW。
我可以有效地利用代码所做的事情,并运行此语句通过DB链接返回一个CLOB,它工作得很好。
select dbms_lob.substr@ARGUS_TRANSCT_DB(NARRATIVE, 4000,1) from ARGUS_CUSTOM.dlp_case_narrative_rowid@ARGUS_TRANSCT_DB where row_id = 'AAATVIAIpAAABzOAAD'
当我尝试将函数作为SQL语句的一部分运行时:
select
ROW_ID,
CASE_ID,
fn_dblink_clob('ARGUS_TRANSCT_DB', 'ARGUS_CUSTOM.dlp_case_narrative_rowid','NARRATIVE', NARR.ROW_ID) as NARRATIVE
from ARGUS_CUSTOM.dlp_case_narrative_rowid@ARGUS_TRANSCT_DB NARR
我得到了这个:
ORA-01446: cannot select ROWID from, or sample, a view with DISTINCT, GROUP BY, etc.
ORA-02063: preceding line from ARGUS_TRANSCT_DB
ORA-06512: at "PV_COMPLIANCE.FN_DBLINK_CLOB", line 22
01446. 00000 - "cannot select ROWID from, or sample, a view with DISTINCT, GROUP BY, etc."
*Cause:
*Action:
所以在视图中没有distinct或group by子句,函数动态地构建语句,我知道,对这个视图执行很好。
远程计算机上的基本视图定义,没有联接、group by或distinct子句。
CREATE VIEW DLP_CASE_NARRATIVE_ROWID
AS
SELECT ROWID AS "ROW_ID", "CASE_ID",
"ABBREV_NARRATIVE",
"DELETED",
"NARRATIVE",
"ABBREV_NARRATIVE_J",
"NARRATIVE_J",
"DLP_REVISION_NUMBER",
"EFFECTIVE_START_DATE",
"EFFECTIVE_END_DATE",
"DELETED_FLAG",
"ENTERPRISE_ID" FROM DLP_OWNER.DLP_CASE_NARRATIVE
1条答案
按热度按时间0s7z1bwu1#
我看到你有一个ROWID(别名为row_id)显式地暴露在你的视图中。只要使用那个...查询row_id而不是rowid。
仅供参考,我已经做了与您相同的事情-创建一个将LOB分块的过程,以便在dblinks上进行更快的处理。但我的做法不同,我将该过程放在远程数据库上,并传入ROWID的集合。该过程将CLOB读取到本地集合中,将其转换为BLOB,压缩它们,然后将其分块到RAW的集合中,将该集合作为OUT参数返回给调用方,该调用方是本地数据库上的过程。该过程与此过程相反,从RAW集合中重新组装BLOB,解压缩,转换为CLOB,然后使用CLOB值更新目标表。出于与您遇到的相同的原因,我也不支持从复杂的视图中拉取数据,因为我的代码需要源代码中的ROWID。但解决方案是重写视图,使其在顶层只有一个表,所有其他连接都通过子查询完成。
我还有一个第一遍机制,它可以将任何小于该大小的CLOB作为VARCHAR 2(4000)(通过CAST)拉取。这比将它们作为CLOB拉取要快得多。但这仍然需要ROWID。
我还应该注意到,虽然这在10多年前给了我相当大的性能提升,超过了Oracle在10 g-11 g时代的原生LOB over dblink,但在最近的版本中,我发现他们已经调整了内部处理,原生LOB传输现在快得多,所以可能不再值得这种黑客式的解决方案。