【问题标题】:HowTo: Update DB row with save for prior to change state如何:在更改状态之前使用保存更新数据库行
【发布时间】:2010-06-01 13:26:57
【问题描述】:

我有一张包含订单详情的表格。用户可以在首次添加这些详细信息后对其进行修改。我的问题是在更新更改之前保存更正确的方法是什么。我的意思不仅仅是主观的思维方式,还有我列出的每种方式的缺点或者你的建议......

我想创建一个与 Orders 相同的 Orders 历史表,所以一旦我更新了一个订单,旧的就会移动到 HistoryOrders 并且这个 Order 也会更新。

另一种方法是在每次使用订单中的父字段时有更新时创建新订单,即。 first Order 的 parentOrderID 为 null,而 update 在 parentOrderID 列行中更新 orderID 之前...

我需要稍后处理这些数据,所以我需要最灵活的解决方案......也许我错过了另一个选择......

CREATE TABLE [dbo].[Orders](
    [orderID] [int] IDENTITY(1,1) NOT NULL,
    [userID] [int] NOT NULL,
    [paymentMethodID] [tinyint] NOT NULL,
    [orderAmount] [smallint] NOT NULL,
    [orderStatusID] [tinyint] NOT NULL,
    [date] [smalldatetime] NOT NULL,
 CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
(
    [orderID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Users] FOREIGN KEY([userID])
REFERENCES [dbo].[Users] ([userID])
GO

ALTER TABLE [dbo].[Orders] CHECK CONSTRAINT [FK_Orders_Users]
GO

谢谢

【问题讨论】:

  • 您使用的是什么版本的 SQL Server?

标签: sql sql-server


【解决方案1】:

当您涉及多个表(父/子)时,这会变得更加复杂,但是在处理单个历史表时,我使用的一般模式是创建两个表,主要的一个:XYZ 和历史一个: XYZ_历史。我有一个插入/更新/删除触发器,它将所有版本复制到 XYZ_History 表中。 XYZ_History 表具有 XYZ 表中的所有列,包括 XYZHistoryID int identity PK、XYZHistoryType char(1) "I"nsert、"U"pdate、"D"elete 和 XYZHistoryDate 日期时间列,即 GETDATE()。如果我需要将“当前”XYZ 值 FK 转换为 XYZ.PK,如果我需要 FK 时间点,我使用 XYZ_History.XYZHistoryID。我在 XYZ_History 上还有一个 UPDATE/DELETE 触发器,它发出一个您无法更改历史记录的错误。

如果不进一步了解您的表结构,很难提供任何具体建议。

【讨论】:

  • 这种方法有点问题,因为我有 Orders2Items 多对多关系表。那么当用户从 Order 中删除一些商品时会发生什么?
  • 你只列出订单的表结构
【解决方案2】:

触发器和历史表是常用的 SQL 方法(如已回答)。但是,根据您需要跟踪更改的原因,外部化状态更改可能是一个非常好的主意。 Unshackle you Domain(Greg Young)对此有一些非常有趣的看法。

总之,如果了解您的更改对您的域/问题很重要,您应该跟踪发生在您的订单上的操作,并通过重新应用发生的所有更改来构建订单的当前状态。而不是保留以下内容:

订单 A 与 Item1 和 Item 3

您存储操作:

  1. 创建订单 A
  2. 添加项目 1
  3. 添加项目 2
  4. 添加项目 3
  5. 删除项目 2

这意味着您可以跟踪所有更改(即使是后来撤消的更改)。当然,这实际上取决于您对历史数据的使用情况。无论如何video 有一些非常棒的想法。

【讨论】:

  • 这将需要我首先获取命令“事务日志”,然后根据事务日志中的命令生成正确的视图......这不是太重了吗?
  • 如果你有很长的交易链,它可能会很重。在视频中有一个滚动快照的想法。它允许您查看到给定时间点的状态并从该点开始应用。我喜欢这个设计,但你需要看看它是否会对你的具体情况有所帮助。
猜你喜欢
  • 2016-01-28
  • 2023-01-28
  • 2021-10-21
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 2017-05-17
  • 2012-12-31
相关资源
最近更新 更多