呼叫 PL/SQL 存儲過程時,若輸入參數為 VARCHAR2 型別且字串長度超過約 1333 個英文字元 (或對應的中文/換行字元),拋出錯誤:
ORA-06502: PL/SQL: numeric or value error: trailing null missing from STR bind value
VARCHAR2 參數在 PL/SQL 呼叫介面 (OCI/OCCI/JDBC) 中有 32767 位元組上限,但某些驅動程式/版本在綁定長字串時,內部緩衝區處理存在缺陷,導致結束空字元 (null terminator) 遺失-- 修改前
CREATE OR REPLACE PROCEDURE process_text (p_input IN VARCHAR2) AS ...
-- 修改後
CREATE OR REPLACE PROCEDURE process_text (p_input IN CLOB) AS
v_text VARCHAR2(32767);
BEGIN
-- 若後續邏輯需 VARCHAR2,可轉換 (注意長度限制)
IF LENGTH(p_input) <= 32767 THEN
v_text := p_input;
-- 原有 VARCHAR2 邏輯
ELSE
-- 處理超長字串邏輯 (分塊、暫存表、DBMS_LOB)
NULL;
END IF;
END;
/
CLOB 支援高達 4GB,無綁定長度限制CREATE OR REPLACE PROCEDURE process_text (p_input IN LONG) AS ...
LONG 為舊型別,Oracle 8i 後已棄用,功能受限 (如無法在 SQL 中使用、不可作為函數參數、不支援 LOB API)-- 定義集合型別
CREATE OR REPLACE TYPE varchar2_table AS TABLE OF VARCHAR2(32767);
-- 存儲過程接收集合
CREATE OR REPLACE PROCEDURE process_long_text (p_chunks IN varchar2_table) AS
v_full_text CLOB;
BEGIN
FOR i IN 1..p_chunks.COUNT LOOP
v_full_text := v_full_text || p_chunks(i);
END LOOP;
-- 處理 v_full_text
END;
/
ojdbc8.jar (12.2+) 或 ojdbc11.jar (19c+)Oracle.ManagedDataAccess NuGet 套件 (19.3+)MAX_STRING_SIZE = EXTENDED 可將 VARCHAR2 擴展至 32767 位元組)-- 測試腳本
DECLARE
v_long_str VARCHAR2(32767) := RPAD('A', 5000, 'A'); -- 5000 字元
BEGIN
process_text(v_long_str); -- 應不再報錯
DBMS_OUTPUT.PUT_LINE('測試通過');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('錯誤: ' || SQLERRM);
END;
/
CLOB 或 VARCHAR2(32767) (需啟用 MAX_STRING_SIZE=EXTENDED)TO_CLOB()、DBMS_LOB.SUBSTR() 處理 LOB 與 VARCHAR2 互轉-- 需以 SYSDBA 執行,資料庫啟動 UPGRADE 模式
ALTER SYSTEM SET MAX_STRING_SIZE = EXTENDED SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP UPGRADE;
@?/rdbms/admin/utl32k.sql;
SHUTDOWN IMMEDIATE;
STARTUP;
-- 之後 VARCHAR2/NVARCHAR2/RAW 最大長度變為 32767 位元組
⚠ 注意:啟用後不可逆,可能影響相容性,生產環境需充分測試。