这确实是个问题,但您可以使用 PL/SQL 作为解决方法:
create or replace function get_doc_length(iDocId in number) return number is
aLong long;
begin
select d.document into aLong from docs d where d.id = iDocId;
return length(aLong);
end;
/
这个函数(不幸的是,它不能使用LONG作为参数,所以必须特定于表DOCS)然后可以像这样使用:
SELECT DOCS.ID
FROM DOCS
where get_doc_length(DOCS.ID) > (60*1024*1024)
编辑:好的,这不适用于大 LONGs。您必须深入挖掘 SQL 的奥秘才能完成这项工作:
create or replace function get_doc_length(iDocId in number) return number is
myQuery varchar2(200);
myCursor binary_integer;
myRes pls_integer;
myDoc clob;
long_val long;
long_len integer;
buf_len integer;
cur_pos number;
begin
myQuery := 'select d.document from docs d where d.id = ' || iDocId;
-- Create cursor, parse and bind.
myCursor := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(myCursor, myQuery, DBMS_SQL.NATIVE);
DBMS_SQL.DEFINE_COLUMN_LONG(myCursor, 01);
myRes := DBMS_SQL.EXECUTE(myCursor);
-- Fetch row (only one normally)
if DBMS_SQL.FETCH_ROWS(myCursor) > 0 then
-- Create CLOB.
DBMS_LOB.CREATETEMPORARY(myDoc, false, DBMS_LOB.CALL);
-- Piecewise fetching of the LONG column, appending to the CLOB.
buf_len := 32760;
cur_pos := 0;
loop
DBMS_SQL.COLUMN_VALUE_LONG(myCursor, 01, buf_len, cur_pos, long_val, long_len);
exit when long_len = 0;
DBMS_LOB.APPEND(myDoc, long_val);
cur_pos := cur_pos + long_len;
end loop;
end if;
DBMS_SQL.CLOSE_CURSOR(myCursor);
return length(myDoc);
end;
/
DBMS_SQL 包允许通过循环将LONG 转换为CLOB 并逐渐附加LONG 的片段。
如果您想要CLOB 的二进制长度而不是其字符长度(这可能会有所不同),您可以使用dbms_lob.getlength 而不是length,如this other SO post 所示。