【问题标题】:Replacing text in a BLOB Column替换 BLOB 列中的文本
【发布时间】:2013-04-26 14:40:59
【问题描述】:

在我们的一张表中,我们有一个 HUGEBLOB 列(列名为 DYNAMIC_DATA),其中包含 XML 数据。我需要做的是从这个 BLOB 中更新文本的某个部分。

我试过这个查询:

UPDATE ape1_item_version 
SET DYNAMIC_DATA = REPLACE (DYNAMIC_DATA,'Single period','Single period period set1') 
WHERE name = 'PRIT ALL POOL for Duration Telephony 10_NA_G_V_H_N_Z2'

但我收到以下错误:

ORA-00932: inconsistent datatypes: expected NUMBER got BLOB

如何在 BLOB 上执行REPLACE

【问题讨论】:

  • 为什么对 XML 使用 BLOB? CLOB 不是更有意义吗?
  • 查看更多信息,orafaq.com/node/895
  • 感谢这个链接,如果它是CLOB,它实际上更正确......但不幸的是我不能改变...... :(
  • 为什么不能改?
  • 这是一个由另一个团队管理的表,我不能直接更改它。但我会告诉他们这件事,希望他们会。

标签: sql oracle replace blob


【解决方案1】:

REPLACE 适用于以下数据类型:

search_string 和 replacement_string 以及 char 都可以是 CHARVARCHAR2NCHARNVARCHAR2CLOBNCLOB 的任何数据类型。

您已选择将字符数据存储为字节集合 (BLOB)。这些不能直接处理,因为 BLOB 没有上下文并且是only a very very big number。没有你的输入就不能转换成字符:你需要它的字符集来把二进制数据转换成文本。

您必须自己编写函数 REPLACE(例如使用 DBMS_LOB.instr)或将数据转换为可用的 CLOB 并在 CLOB 上使用标准函数。

我强烈建议您更改列的数据类型。这将防止您将来可能会遇到任何进一步的字符集转换错误。

如果您真的想使用 blob,请使用以下函数:

SQL> CREATE OR REPLACE FUNCTION convert_to_clob(l_blob BLOB) RETURN CLOB IS
  2     l_clob         CLOB;
  3     l_dest_offset  NUMBER := 1;
  4     l_src_offset   NUMBER := 1;
  5     l_lang_context NUMBER := dbms_lob.default_lang_ctx;
  6     l_warning      NUMBER;
  7  BEGIN
  8     dbms_lob.createtemporary(l_clob, TRUE);
  9     dbms_lob.converttoclob(dest_lob     => l_clob,
 10                            src_blob     => l_blob,
 11                            amount       => dbms_lob.lobmaxsize,
 12                            dest_offset  => l_dest_offset,
 13                            src_offset   => l_src_offset,
 14                            blob_csid    => nls_charset_id('AL32UTF8'),
 15                            lang_context => l_lang_context,
 16                            warning      => l_warning);
 17     RETURN l_clob;
 18  END convert_to_clob;
 19  /

Function created

SQL> CREATE OR REPLACE FUNCTION convert_to_blob(l_clob CLOB) RETURN BLOB IS
  2     l_blob         BLOB;
  3     l_dest_offset  NUMBER := 1;
  4     l_src_offset   NUMBER := 1;
  5     l_lang_context NUMBER := dbms_lob.default_lang_ctx;
  6     l_warning      NUMBER;
  7  BEGIN
  8     dbms_lob.createtemporary(l_blob, TRUE);
  9     dbms_lob.converttoblob(dest_lob     => l_blob,
 10                            src_clob     => l_clob,
 11                            amount       => dbms_lob.lobmaxsize,
 12                            dest_offset  => l_dest_offset,
 13                            src_offset   => l_src_offset,
 14                            blob_csid    => nls_charset_id('AL32UTF8'),
 15                            lang_context => l_lang_context,
 16                            warning      => l_warning);
 17     RETURN l_blob;
 18  END convert_to_blob;
 19  /

Function created

您可以直接从 SQL 调用这些函数:

SQL> UPDATE ape1_item_version
  2     SET DYNAMIC_DATA = convert_to_blob(
  3                          REPLACE(convert_to_clob(DYNAMIC_DATA),
  4                                 'Single period',
  5                                 'Single period period set1')
  6                          )
  7   WHERE NAME = 'PRIT ALL POOL for Duration Telephony 10_NA_G_V_H_N_Z2';

1 row updated

【讨论】:

  • 是的,该字段是 BLOB 而不是 CLOB。无论如何版本是Ora11.1
【解决方案2】:

如果 blob 对象是文本,我们也可以在 Oracle 11 及更高版本中使用类似下面的查询。

`UPDATE table_name
SET text_blob_column-name = UTL_RAW.CAST_TO_RAW(
REPLACE(UTL_RAW.CAST_TO_VARCHAR2(text_blob_column-name),
'<existing value>',
'<value to update>')
)
WHERE where_clause_Column-name='171';`

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-27
    • 2015-10-19
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多