我有一個簡單的函式可以將 html blob 轉換為純文本
FUNCTION HTML_TO_TEXT(html IN CLOB) RETURN CLOB
IS v_return CLOB;
BEGIN
select utl_i18n.unescape_reference(regexp_replace(html, '<. ?>', ' ')) INTO v_return from dual;
return (v_return);
END;
以這種方式呼叫:
SELECT A, B, C, HTML_TO_TEXT(BLobField) FROM t1
一切正常,直到 BlobFields 包含超過 4000 個字符,然后我得到了
ORA-01704: string literal too long
01704. 00000 - "string literal too long"
*Cause: The string literal is longer than 4000 characters.
*Action: Use a string literal of at most 4000 characters.
Longer values may only be entered using bind variables.
我嘗試使用變數在函式內部避免字串,但沒有任何變化:
FUNCTION HTML_TO_TEXT(html IN CLOB) RETURN CLOB
IS v_return CLOB;
"stringa" CLOB;
BEGIN
SELECT regexp_replace(html, '<. ?>', ' ') INTO "stringa" FROM DUAL;
select utl_i18n.unescape_reference("stringa") INTO v_return from dual;
return (v_return);
END;
uj5u.com熱心網友回復:
不要使用正則運算式來決議 HTML。如果要提取文本,請使用 XML 決議器:
SELECT a,
b,
c,
UTL_I18N.UNESCAPE_REFERENCE(
XMLQUERY(
'//text()'
PASSING XMLTYPE(blobfield, 1)
RETURNING CONTENT
).getStringVal()
) AS text
FROM t1
這將在提取的文本為 4000 個字符或更少的情況下作業(因為XMLTYPE.getStringVal()將回傳VARCHAR2資料型別并UTL_I18N.UNESCAPE_REFERENCE接受VARCHAR2引數)。
如果你想讓它在CLOB值上作業,那么你仍然可以使用XMLQUERY, getClobVal()但 UTL_I18N.UNESCAPE_REFERENCE仍然只能在VARCHAR2輸入(而不是CLOBs)上作業,所以你需要將它們拆分CLOB成段并決議它們并在完成后將它們連接起來。
就像是:
CREATE FUNCTION html_to_text(
i_xml IN XMLTYPE
) RETURN CLOB
IS
v_text CLOB;
v_output CLOB;
str VARCHAR2(4000);
len PLS_INTEGER;
pos PLS_INTEGER := 1;
lim CONSTANT PLS_INTEGER := 4000;
BEGIN
SELECT XMLQUERY(
'//text()'
PASSING i_xml
RETURNING CONTENT
).getStringVal()
INTO v_text
FROM DUAL;
len := LENGTH(v_text);
WHILE pos <= len LOOP
str := DBMS_LOB.SUBSTR(v_text, lim, pos);
v_output := v_output || UTL_I18N.UNESCAPE_REFERENCE(str);
pos := pos lim;
END LOOP;
RETURN v_output;
END;
/
但是,您可能希望使其更加健壯并檢查是否要在轉義的 XML 字符中間拆分字串。
db<>在這里擺弄
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/494498.html
