【问题标题】:CLOB Commits not working when run back to backCLOB 提交在背靠背运行时不起作用
【发布时间】:2018-03-08 15:52:48
【问题描述】:

我们正在运行较旧的 Oracle 服务器 10.1.0.5。

我有一些简单的代码将不同列中的一个 CLOB 替换为另一个。 我正在用不同列中的另一个更简单的字符串替换特定字符串,因此我可以执行一些基本的 XML 解析。参考:here.

我希望执行一系列更新命令,每个命令之间都有提交,并正确更新所有字段。如果我按如下方式运行它,尽管作为脚本运行,但只有最后一个查询被提交。间歇性提交似乎不需要。

我可以通过逐行运行每个更新 + 提交来使其工作,但我想知道为什么我不能一次运行所有这些。我只展示了前 2 个更新。我错过了什么?

set define off

update TABLE1 SET COL_CLEANED = replace(COL_ORIGINAL,' ',  ' ');
COMMIT;

update TABLE1 SET COL_CLEANED = replace(COL_ORIGINAL,'§',  'SECT.');
COMMIT;

update TABLE1 ...

谢谢,

sse

【问题讨论】:

  • 您正在更新同一个字段,COL_CLEANSED 两次,第二次将覆盖第一次。除非您遇到错误,否则我怀疑是否发生了回滚。
  • 你当然是对的,谢谢!

标签: xml oracle clob xmltype xmltable


【解决方案1】:

正如@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 对您当前存储的值的引用;因为真正的原始文本将有 § 以使其被转义为 §,所以无论如何将其恢复为该原始字符可能更合适。除非您最终遇到无法显示的字符集。

【讨论】:

  • 正确。感谢您提供有关 UNESCAPE_REFERENCE 的其他辅助信息。你是对的,关于章节字符。我们遇到的问题是数据库太旧并且使用 USACII7 编码和 BYTE Semantics。在我们迁移到现代字符集之前,恢复它不是一种选择。再次感谢!
猜你喜欢
  • 2021-09-26
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
相关资源
最近更新 更多