【问题标题】:Update Clob value using SQL使用 SQL 更新 Clob 值
【发布时间】:2021-06-28 15:15:36
【问题描述】:

我有一张桌子 xyz 我在其中有一个 clob(假设是一个)

我的 clob 结构如下所示

<XML version ="1.0"?>
<properties>
   <property name ="tran_start_date">
   <value>1/1/2021</value>
   </property>
    <property name ="tran_end_date">
   <value>21/12/2021</value>
   </property>
   <property name ="accn_no">
   <value>12838372882</value>
   </property>
</properties>

现在我想将 tran_start_date 更新为 30/10/2021, Trans_end_date 至 2022 年 10 月 30 日, 和accn_no到098765

如何为此编写更新查询...我正在使用 oracle 数据库

【问题讨论】:

  • 你已经尝试过什么?你有示例代码要分享吗?
  • 更好的问题 - 为什么要对 XML 数据使用 CLOB 数据类型?
  • @mathguy,Oracle 是否支持其他东西来存储 XML 数据?
  • @AnkitBajpai - xmltype 数据类型是 20 年前在 Oracle 9.0.1 中引入的。您可以通过简单的 Google 搜索(例如短语“Oracle xml 数据类型”)更快地自己发现这一点。
  • @mathguy,感谢分享。

标签: sql database oracle sql-update clob


【解决方案1】:

我会回答一个稍微不同的问题 - 看看是否有帮助。

在我的 cmets 中,我提出了两个问题。首先,您的clob 看起来像一个XML 文档,所以它应该存储在数据类型为xmltype 的列中,而不是clob。 (这类似于将日期存储为字符串而不是正确的 date 数据类型。)其次,您的“XML 文档”实际上不是有效的 XML 文档,因为它的序言中有两个主要错误:@ 987654325@ 在打开 &lt; 后立即丢失,XML 应该是 xml(小写)。两者都是致命错误,不允许您将该字符串存储为xmltype。 (这也类似于将日期存储为字符串,并且有一个类似 '31 February 2020' 的字符串 - 您可以将其存储为字符串,但如果您尝试将其存储在 date 列中,Oracle 会立即告诉您一些信息错了。)

在下面的解决方案中,我将数据类型保留为CLOB - 但我将在其中存储一个有效的 XML 文档。下面是创建示例表的代码:

create table xyz (a clob);

insert into xyz values (
'<?xml version ="1.0"?>
<properties>
   <property name ="tran_start_date">
   <value>1/1/2021</value>
   </property>
    <property name ="tran_end_date">
   <value>21/12/2021</value>
   </property>
   <property name ="accn_no">
   <value>12838372882</value>
   </property>
</properties>'
);

commit;

那么这是根据您的要求更新它的一种方法。我使用xmlquery作为主要工具;但是,由于您的列类型是clob,我必须先将其转换为xmltype(使用xmltype() 构造函数),并且在xmltype 更新完成后,我必须将xmltype 转换回@987654340 @;这就是xmlserialize 所做的。我将indent 选项用于xmlserialize;您的输入没有遵循任何系统缩进,因此结果的缩进将与原始内容略有不同。我希望没关系。 (作为 XML 文档,这无关紧要。)

update xyz
  set a =
    xmlserialize(document
      xmlquery(
          'copy $t := $x
            modify(
              (for $i in $t/properties/property[@name="tran_start_date"]/value
               return replace value of node $i with "30/10/2021")
            , (for $i in $t/properties/property[@name="tran_end_date"]/value
               return replace value of node $i with "30/10/2022")
            , (for $i in $t/properties/property[@name="accn_no"]/value
               return replace value of node $i with "098765")
            ) return $t'
            passing xmltype(a) as "x" returning content
      )
    indent size = 2)
;

commit;

这演示了更新值的最简单方法 - 新值直接硬编码到 xmlquery。这可以通过在xmlquerypassing 子句中传递新值来更通用;究竟如何做到这一点取决于您首先如何将这些运行时值提供给 update 语句。

现在检查表中的内容:

select a from xyz;

A                                                                               
------------------------------------------------------------
<?xml version="1.0"?>
<properties>
  <property name="tran_start_date">
    <value>30/10/2021</value>
  </property>
  <property name="tran_end_date">
    <value>30/10/2022</value>
  </property>
  <property name="accn_no">
    <value>098765</value>
  </property>
</properties>

【讨论】:

  • 谢谢,非常感谢你解释的方式,如果可能的话,你能解释一下 xmlquery() 函数中的代码吗?
  • @SauravKumar - 不是真的。 XMLQuery 是一个非常大的主题,如果您需要操作 XML 文档(在任何环境中,而不仅仅是在 Oracle 数据库中),您应该学习它,但这不是一个可以在对网站上的答案的评论中教授的东西这。作为一个简短的总结——这里的代码将输入的 XMLtype 对象作为一个名为“x”的变量传入,并将其复制到一个新的变量“t”中。然后它通过替换您指定的三个节点值来修改 t。 XMLQuery 函数然后返回 XML 文档的修改版本。这对你有多大帮助,我不知道。
  • @mathaguy 帮助了我很多,谢谢 -_- 。
猜你喜欢
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 2011-12-29
  • 2016-07-19
  • 2010-12-01
相关资源
最近更新 更多