Oracle 追加到 clob
Oracle appending to a clob
我有一个工作场景,每次更新期间都会向 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;
/
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 位置的新定位器(我们称之为 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。当程序 returns 时,它会立即被丢弃。 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;
/
我有一个工作场景,每次更新期间都会向 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;
/
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 位置的新定位器(我们称之为 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。当程序 returns 时,它会立即被丢弃。 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;
/