Microsoft SQL 触发器:指向同一记录的多个连接记录会更新失败吗?

发布于 2024-10-04 16:05:41 字数 1366 浏览 1 评论 0原文

背景:

  • 我有一组从 1 开始的每个编号周的产品。
  • 我有一个产品“库”,它是第零周,保存任何时间段内最后保存的产品。
  • 我有一个在更新或插入时触发的触发器,它使“库”项目与插入的项目保持最新。

由于使用“序列”字段在同一事件中可能存在重复的产品,因此我的加入将创建多个记录以进行更新,这些记录针对相同的库记录。

一些问题:

  • 这些倍数会使更新命令失败吗?
  • 有没有更好的方法来更新单库产品?

代码:

-- PK is ID, Week #, and Sequence #
update p set p.name = i.name
from product p join inserted i on
     p.id = i.id and p.week = 0 and p.sequence = 1 

注意:“插入”可以有多个事件。 ID 就像 UPC,Week 是一个身份,Sequence 也像一个身份,但每周从 1 开始。您可以拥有 2 的序列,但不能拥有 1 的序列,因为它们可以删除产品。

示例数据:

 ID  序列  名称  
12345 1     3     乐高  ;  首先插入
12345 2     2    乐高玩具 插入第二个
12345 2     3    乐高玩具 插入第二个

结果数据:

 ID  序列  名称  < /kbd>
12345 0     1    乐高玩具 以前的“乐高”现在是“乐高玩具”

Background:

  • I have a set of products for each numbered week starting at 1.
  • I have a product "library" which is week zero holding the last saved product from any time period.
  • I have a trigger that fires upon update or insert which keeps the "library" item up to date from the inserted items.

Since there can be duplicate products in the same event using a "sequence" field, my join will create multiple records to update from, which target the same library record.

Some questions:

  • Will these multiples fail the update command?
  • Is there a better way to update the single library product?

Code:

-- PK is ID, Week #, and Sequence #
update p set p.name = i.name
from product p join inserted i on
     p.id = i.id and p.week = 0 and p.sequence = 1 

Note: "inserted" can have multiple events. ID is like a UPC, Week is an identity, and Sequence is like an identity, but starts at 1 for each week. You can have a sequence of 2 while not having a sequence of 1 because they can delete products.

Sample Data:

 ID  WeekSequence  Name  
12345 1     3      Lego   inserted first
12345 2     2    Lego Toy inserted second
12345 2     3    Lego Toy inserted second

Result data:

 ID  WeekSequence  Name  
12345 0     1    Lego Toy Was "Lego" now is "Lego Toy"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

零崎曲识 2024-10-11 16:05:41

根据 BOL 条目:

指定 FROM 时要小心
条款提供标准
更新操作。结果
如果 UPDATE 语句未定义
语句包含一个 FROM 子句
没有以这样的方式指定
每个只有一个值可用
更新的列出现次数,
也就是说,如果 UPDATE 语句是
不是确定性的。

换句话说,如果 UPDATE 语句使用具有多行满足条件的 FROM 子句来更新单行,则不知道将使用哪一行新数据。在您的示例数据中,尚不清楚结果是根据 Sequence=2 还是 Sequence=3 行中的名称进行更新。

因此,如果使用哪一行进行更新并不重要,那么您当前正在执行的操作就可以正常工作。但是,如果这是一个问题,您需要编写更新的 FROMWHERE 子句,以便为每个项目仅返回一行,可能类似于以下内容:

;with insert2 as (
  select id, week, sequence, name,
         row_number() over(partition by id order by week desc, sequence desc) as [descOrd]
  from inserted
)
update p
set p.name = i.name
from product p
  join insert2 i on p.id = i.id and p.week = 0 and p.sequence = 1
where i.descOrd=1

According to this BOL entry:

Use caution when specifying the FROM
clause to provide the criteria for the
update operation. The results of an
UPDATE statement are undefined if the
statement includes a FROM clause that
is not specified in such a way that
only one value is available for each
column occurrence that is updated,
that is, if the UPDATE statement is
not deterministic.

In other words, if an UPDATE statement uses a FROM clause that has multiple rows meeting the criteria to update a single row, it is unknown which row of new data will be used. In your sample data, it is unknown whether the result was updated from the name in the row with Sequence=2 or Sequence=3.

So, if it doesn't matter which row is used for the update, what you're currently doing will work just fine. If this is a problem however, you need to write your update's FROM and WHERE clauses so that only one row is returned for each item, possibly something like the following:

;with insert2 as (
  select id, week, sequence, name,
         row_number() over(partition by id order by week desc, sequence desc) as [descOrd]
  from inserted
)
update p
set p.name = i.name
from product p
  join insert2 i on p.id = i.id and p.week = 0 and p.sequence = 1
where i.descOrd=1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文