【问题标题】:Oracle: Safely change value(s) in table, if not new entry already exists, remove the old oneOracle:安全地更改表中的值,如果不存在新条目,则删除旧条目
【发布时间】:2020-09-07 22:15:19
【问题描述】:

我有一个像这样的表格

table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}

th, td {
  padding: 2px;
}

th {
  text-align: left;
}
<table style="width:40%">
  <tr>
    <th>COL_1[PK]</th>
    <th>COL_2[PK]</th>
    <th>COL_3</th>
  </tr>
  <tr>
    <td>A</td>
    <td>Bar</td>
    <td>4</td>
  </tr>
  <tr>
    <td>B</td>
    <td>Foo</td>
    <td>8</td>
  </tr>
  <tr>
    <td>C</td>
    <td>Foo</td>
    <td>15</td>
  </tr>
  <tr>
    <td>C</td>
    <td>NewFoo</td>
    <td>15</td>
  </tr>
  <tr>
    <td>D</td>
    <td>Foo</td>
    <td>16</td>
  </tr>
  <tr>
    <td>E</td>
    <td>Bar</td>
    <td>23</td>
  </tr>
  <tr>
    <td>...</td>
    <td>...</td>
    <td>...</td>
  </tr>
</table>

我想将COL_2 = 'Foo' 的所有行更改为NewFoo。问题是某些行已经更改而没有删除旧值。所以如果我运行命令

update TABLE
set COL_2 = 'NewFoo'
where COL_2 = 'Foo'

但是,当我尝试将第三行 (C, Foo, 15) 更改为 (C, NewFoo, 15) 时会遇到麻烦,因为该条目已经存在。

对此的一种解决方案是简单地删除之前已更改的所有行并再次转换它们:

delete from TABLE where COL_2 = 'NewFoo';
update table
set COL_2 = 'NewFoo'
where COL_2 = 'Foo';

这将正常工作,直到有人在同一张桌子上运行脚本两次。第一次所有旧转换将被删除,所有 'Foo' 值将转换为 'NewFoo'(根据需要)。第二次执行脚本时,所有转换后的记录都会被删除。

我正在寻找一种方法来做到这一点,而不必担心有人运行脚本两次。我认为解决方案看起来像这些示例中的内容,但我无法弄清楚如何形成陈述

Oracle insert if not exists statement

Oracle: how to INSERT if a row doesn't exist

【问题讨论】:

  • 不错的 CSS 工作 +1,但为了将来参考,纯文本表格也可以。

标签: sql oracle


【解决方案1】:

我找到了解决方案(Tim Biegeleisen 的回复让我朝着正确的方向前进。)

这将起作用并保存以多次运行

UPDATE table_name as t1
SET COL_2 = 'NewFoo'
WHERE
    COL_2 = 'Foo' AND
    NOT EXISTS (SELECT 1 FROM table_name as t2 WHERE t2.COL_1 = t1.COL_1 AND t2.COL_2 = 'NewFoo');

delete from table_name
WHERE COL_2 = 'Foo';

【讨论】:

  • 写这个答案没有意义,你最好在我的下面发表评论。您的问题没有明确“重复”的定义是什么,鉴于您提供的信息,我发布的内容是合理的。
【解决方案2】:

在您的更新中使用EXISTS 子句来排除新更新记录的存在:

UPDATE yourTable t1
SET COL_2 = 'NewFoo'
WHERE
    COL_2 = 'Foo' AND
    NOT EXISTS (SELECT 1 FROM yourTable t2
                WHERE t2.COL_3 = t1.COL_3 AND t2.COL_1 = t1.COL_1 AND t2.COL_2 = 'NewFoo');

【讨论】:

  • @RasmusN 我想我忘了检查COL_1 的值,抱歉。检查上面的更新答案。
  • 啊,是的,我注意到了。刚刚自己回复了,谢谢更新。
猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
相关资源
最近更新 更多