我有一個作業場景,每次更新期間都會向 CLOB 添加換行符。
我有一個類似的場景,下面,似乎不起作用。我不明白為什么,并希望有人能解釋問題是什么,因為我更喜歡將換行代碼嵌入到程式中,而不是讓用戶每次更新時都必須添加它。
-- Works
ALTER SESSION SET NLS_DATE_FORMAT = 'MMDDYYYY HH24:MI:SS';
CREATE table t(
seq_num integer GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
c CLOB,
create_date DATE DEFAULT SYSDATE
);
/
insert into t (c) values (
rpad('X',20,'X')
);
/
create or replace procedure lob_append( p_id in number, p_text in varchar2 )
as
l_clob clob;
begin
select c into l_clob from t where seq_num = p_id for update;
dbms_lob.writeappend( l_clob, length(p_text), p_text );
end;
/
select * from t;
/
exec lob_append(1, chr(10)|| rpad('Z',20,'Z'));
/
select * from t;
/
-- Doesn't work
DROP table t;
/
CREATE table t(
seq_num integer GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
c CLOB,
create_date DATE DEFAULT SYSDATE
);
/
insert into t (c) values (
rpad('X',20,'X')
);
/
create or replace procedure lob_append( p_id in number, p_text in varchar2 )
as
l_clob clob;
begin
select c into l_clob from t where seq_num = p_id for update;
-- newline not added
l_clob := l_clob || chr(10);
dbms_lob.writeappend( l_clob, length(p_text), p_text );
end;
/
select * from t;
/
-- Data not added
exec lob_append(1, rpad('Z',20,'Z'));
select * from t;
/
uj5u.com熱心網友回復:
select c into l_clob from t where seq_num = p_id for update;
此時,您的代碼中l_clob包含一個lob 定位器(我們稱之為 LOCATOR_A),它指向資料庫中的特定字串。如果您呼叫dbms_lob.writeappend(l_clob, ...)它,它將使用新值更新 LOCATOR_A 處的字串。
l_clob := l_clob || chr(10);
當您呼叫此行時,第一部分l_clob || chr(10)創建一個指向臨時 CLOB 位置的 NEW lob 定位器(我們稱之為 LOCATOR_B),并為其提供字串值 換行符。第二部分l_clob := value將臨時 lob 定位符 LOCATOR_B 分配給l_clob變數。此時,您已經丟失了對存盤在資料庫中的永久 lob 指標 LOCATOR_A 的參考。
dbms_lob.writeappend( l_clob, length(p_text), p_text )
現在更新臨時 lob LOCATOR_B。當程序回傳時,它立即被丟棄。LOCATOR_A 指向的資料庫clob 沒有改變。
我建議將換行符添加到您的 varchar2 中,這樣您就不會創建新的臨時 Clob。
create or replace procedure lob_append( p_id in number, p_text in varchar2 )
as
l_clob clob;
begin
select c into l_clob from t where seq_num = p_id for update;
p_text := chr(10) || p_text;
dbms_lob.writeappend( l_clob, length(p_text), p_text );
end;
/
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/327519.html
