正如@OldProgrammer 所说,您反复替换COL_CLEANED 值并覆盖之前的更改...
假设您从一个需要多次替换的简单值开始:
create table table1 (col_original clob, col_cleaned clob);
insert into table1 (col_original)
values (to_clob('Test without breaks - §1'));
并进行了第一次更新:
update TABLE1 SET COL_CLEANED = replace(COL_ORIGINAL,' ', ' ');
select col_original, col_cleaned from table1;
COL_ORIGINAL COL_CLEANED
---------------------------------------- ----------------------------------------
Test without breaks - §1 Test without breaks - §1
现在进行第二次更新:
update TABLE1 SET COL_CLEANED = replace(COL_ORIGINAL,'§', 'SECT.');
select col_original, col_cleaned from table1;
COL_ORIGINAL COL_CLEANED
---------------------------------------- ----------------------------------------
Test without breaks - §1 Test without breaks - SECT.1
没有提交也没有回滚。但是您采用了 original 值 - 它仍然具有旧模式 - 并替换了其中的第二个模式。第一次更新被第二次覆盖了。
您需要对 cleaned 值应用连续更新;只有第一次更新使用原始值:
-- first update is based on COL_ORIGINAL
update TABLE1 SET COL_CLEANED = replace(COL_ORIGINAL,' ', ' ');
select col_original, col_cleaned from table1;
COL_ORIGINAL COL_CLEANED
---------------------------------------- ----------------------------------------
Test without breaks - §1 Test without breaks - §1
-- subsequent updates are based on COL_CLEANED to keep earlier changes
update TABLE1 SET COL_CLEANED = replace(COL_CLEANED,'§', 'SECT.');
--------------------------------------------^^^^^^^
select col_original, col_cleaned from table1;
COL_ORIGINAL COL_CLEANED
---------------------------------------- ----------------------------------------
Test without breaks - §1 Test without breaks - SECT.1
顺便说一句,实际上并不需要提交;您应该为每个逻辑事务提交一次,而不是每个语句一次。
顺便说一句,您可以为此使用the utl_i18n.unescape_reference() function,但在您的示例中,它将为您提供多字节“节”字符而不是字符串'SECT.':
update TABLE1 SET COL_CLEANED = UTL_I18N.UNESCAPE_REFERENCE(COL_ORIGINAL);
select col_original, col_cleaned from table1;
COL_ORIGINAL COL_CLEANED
---------------------------------------- ----------------------------------------
Test without breaks - §1 Test without breaks - §1
它可能会做出与您的其他硬编码替换不同的其他更改。另一方面,在某些时候,您的col_original 可能已经通过类似的函数传递给escape 对您当前存储的值的引用;因为真正的原始文本将有 § 以使其被转义为 §,所以无论如何将其恢复为该原始字符可能更合适。除非您最终遇到无法显示的字符集。