在oracle19c中,有个函数getlong,可以在查询sql中将long类型的字段返回成varchar2类型,用法如下
select getlong(1,rowid),t.* from VIEW$ t;
但是需要注意,这个函数只能查两个表里的long类型,内部实现如下
if (opcode = 1) then
tablename := 'SYS.VIEW$';
colname := 'TEXT';
elsif (opcode = 2) then
tablename := 'SYS.CDEF$';
colname := 'CONDITION';
else
return NULL;
end if;
stmt := 'SELECT ' || colname || ' FROM ' || tablename ||
' WHERE ROWID = :1';
CDBView_internal.long2varchar2_i(stmt, p_rowid, retval);
return retval;
如果需要支持查其他表的,需要再自行封装,调用CDBView_internal.long2varchar2_i
从rowid里,理论上是可以解析出来对应的表的,感觉ORACLE这里的实现其实有点草台班子了。至于字段名,也可以传个字段名的字符串进去
其实ORACLE的处理思路和aktom的一个帖子比较像 https://asktom.oracle.com/ords/f?p=100:11:0::::P11_QUESTION_ID:839298816582
成品
create or replace function long2varchar(p_colname in varchar2, p_rowid in rowid)
return varchar2 as
tablename dbms_id;
stmt varchar2(400);
retval varchar2(4000);
PROCEDURE long2varchar2_i(stmt IN VARCHAR2,
rowid IN ROWID,
rowval IN OUT VARCHAR2) IS
EXTERNAL NAME "kpdbLong2Varchar2"
LANGUAGE C
LIBRARY DBMS_PDB_LIB
PARAMETERS(stmt OCIString,
stmt indicator sb4,
rowid OCIString,
rowid indicator sb4,
rowval OCIString,
rowval indicator sb4,
rowval length sb4,
rowval maxlen sb4);
begin
select owner || '.' || object_name
into tablename
from dba_objects t
where t.data_object_id = dbms_rowid.rowid_object(p_rowid);
stmt := 'SELECT ' || p_colname || ' FROM ' || tablename ||
' WHERE ROWID = :1';
long2varchar2_i(stmt, p_rowid, retval);
return retval;
end;
select long2varchar('TEXT',rowid),t.* from VIEW$ t;