【问题标题】:Oracle PL/SQL Update duplicate and null rows with random sys_guid() and add primary keyOracle PL/SQL 使用随机 sys_guid() 更新重复和空行并添加主键
【发布时间】:2016-11-23 16:24:34
【问题描述】:

我有一个包含数百万行的巨大表格。

它有一个 GUID RAW(16 字节)列。由于某种原因/疏忽,该表从未有主键约束,并且由于代码中的错误已将重复项插入 GUID 列(以及一些空值)

我想做的是:

  • 使用随机生成的 GUID 更新 GUID 为 NULL 的所有行(可能使用 SYS_GUID())
  • 使用随机生成的 GUID 更新所有 GUID 重复的行
  • 使用 GUID 列向表中添加主键。

不必保留 GUID 值,它们都必须是唯一的。但是有问题的表有大约 3 亿条记录,所以我正在寻找一种不会导致太多停机时间的方法。

谢谢

【问题讨论】:

  • 什么构成重复?我们需要知道哪个记录是“原始的”,这样它就不应该被替换。请包括表结构。
  • 没有重复行,只有 guid 值重复。因此,一些完全不同的记录具有相同的 guid。
  • 您有 3 个相同的 GUID。我们如何知道要更改哪一个,或者应该更改所有 3 个?能发一下表结构吗?

标签: sql oracle guid


【解决方案1】:

我会使用合并语句,类似于:

merge into your_table tgt
  using (select guid,
                row_id
         from   (select guid,
                        rowid row_id,
                        row_number() over (partition by guid order by rowid) rn
                 from   your_table)
         where  rn != 1) src
  on (tgt.rowid = src.rowid)
when matched then
update set guid = null;

添加唯一索引,然后进行更新:

update your_table
set    guid = sys_guid()
where  guid is null;

然后将您的 guid 列更改为不可为空,最后添加主键约束。

或者,您可以在合并中将 null 和重复的 guid 行更新到 sys_guid(),但您会冒着创建重复 guid 的风险。事实上,最终更新可能仍然会失败,因为 sys_guid() 不一定能保证生成唯一值。

就个人而言,我会放弃 guid(尽管我意识到这并不总是可能的)并按顺序进行;这更容易保证唯一性!

【讨论】:

  • 谢谢,这似乎可以解决问题。不幸的是,在我的情况下,无法取消 guid。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-05
  • 1970-01-01
  • 2010-10-25
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
相关资源
最近更新 更多