【问题标题】:Multiple inserts and updates in on SQLSQL 中的多个插入和更新
【发布时间】:2014-05-07 06:48:07
【问题描述】:

您好,我目前正在尝试在一个 sql 中进行多次更新和插入。

我有一个表,我在其中加载具有以下列的数据:

  • 行号
  • 开始日期
  • 结束日期
  • 其他数据列

此表是数据的历史表视图。行号是给定开始和结束期间从 1 到编号记录的行数。这意味着如果它包含 1980 年到结束时间的 100 条记录,那么它在该期间有 1 到 100 条记录。

如果说记录 3 已从 2014 年 4 月 1 日到结束时间被删除,那么记录号 3 之后的所有记录都需要将其行号减 1 以确保行号没有间隙。此外,这反过来意味着我们需要在之后拆分所有记录,这样当您在 2014 年 4 月 1 日之前查看表时,您会看到 100 行。但是在您看到 99 行之后的任何时间。这实质上意味着将记录 4-100 的结束时间更新为 2014 年 3 月 31 日,并插入从 2014 年 4 月 1 日到插入时间结束的新记录,这是一个副本,即数据与行号减 1 相同.

现在我想避免进行许多单独的更新和插入。即每个 90+ x 2。我希望有一种聪明的方法可以通过单个 sql 或少于 90 个左右来完成此操作。

我的想法是这样的

Update table set rownumber=rownumber -1 where rownumber > 3 (Deleted rownumber)

当然这个例子不处理时间的分割和插入

我在 oracle 11g 下运行。 我不能更改表结构,我必须保持行号一致并且在一段时间内没有间隙。此外,任何更新或插入都在这张表上。

任何建议提示将不胜感激。

【问题讨论】:

  • 我会说螺丝行号更新,只是在显示时给它们编号。
  • 行号是不能忽略的,有其他程序访问这个表依赖于行号。这是我无法控制的,很遗憾我无法改变,否则问题不会那么困难。
  • 您需要一个插入、更新和删除触发器来重新编号行,这需要每个触发器运行 1 到 2 次更新语句。抱歉帮不上忙,因为我没有编写可以执行递归的触发器的经验。
  • 再说一遍,我不能修改这个表。
  • 据我了解,您说过您不能更改表的结构,也不能更新其内容。触发器不会改变表的结构,它是 SQL Server 响应特定请求(插入、更新或选择)执行的操作,具体取决于 DBA 的需要。

标签: sql database performance oracle


【解决方案1】:

将 rownum 存储在表中是一种不好的编程习惯。 而不是存储它..更新您的表结构以删除rownum列,并且您需要检索它只需添加伪列名rownum。 所以

select rownum, <column list> from <table name>

会做同样的工作。并且您不需要每次都更新。

除非您特别需要存储 rownum 列,否则不要为其创建列。

请指定需要存储 rownum 列的用例..??

那么我可以帮助你。

用户发表评论后编辑:

对 rownum 更新使用以下语句:

update table t1 set rownum_col=(select rn from (select rownum rn, pk1 , pk2 from table ) t2 where t1.pk1=t2.pk1 and t1.pk2=t2.pk2);

【讨论】:

  • 我说过我不能修改表结构,这不是我能控制的。这是限制之一。行号用于访问该表的系统的其他部分。又是我无法控制的事情
  • 谢谢你,但它仍然没有处理记录的时间分割,所以在需要的地方进行插入。
【解决方案2】:

我不确定我是否理解关于拆分行的部分,但要对所有行进行顺序编号,您可以使用以下内容:

merge into the_table
using
(
   select rowid as rid,
          row_number() over (order by start_date) as new_rownumber
   from the_table
) t on (t.rid = the_table.rowid) 
when matched then update 
  set rownumber = new_rownumber;

如果整个表的行号不是“全局”的,则需要在窗口函数中添加partition by 子句以重新对不同“块”数据进行编号。

【讨论】:

  • 考虑以下情况,表中有一条从 1980 年 1 月 1 日开始到时间结束的记录。如果此记录随后在差异期间修改,例如 1/4/2014,则数据库中的原始记录必须保持其数据不变,但我们需要将此记录的结束时间更改为 -1 秒小于 1/4 /2014。然后需要将新的更改作为从 2014 年 4 月 1 日到时间结束的新记录插入。有效地将原始记录拆分为两条记录。我想避免做单次更新和单次插入,我希望在更高效的 SQL 查询中做到这一点
猜你喜欢
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多