【问题标题】:SQL Server stored procedure to store Latest Value and History table用于存储最新值和历史记录表的 SQL Server 存储过程
【发布时间】:2015-11-27 00:57:42
【问题描述】:

正在寻找一种方法来做到这一点是 SQL Server

表 1 - Status_Latest

DeviceID Status(bit) TimeOfUpdate(datetime)

表 2 - Status_History

DeviceID Status(bit) TimeOfUpdate(datetime)

寻找最快的实现方式:

调用存储过程,传递DeviceID 和状态。

如果Status_Latest 中不存在DeviceID,请同时插入Status_LatestStatus_History

如果值与Status_Latest 中的当前值不同,请更新它 并存储到Status_History

我在想

选项 A:如果值不同,我可以从 Status_Latest 中进行选择,然后更新 Status_LatestStatus_History

选项 B:我可以在存储旧值的同时更新 Status_Latest? 如果值不同更新Status_LatestStatus_History

到目前为止我所拥有的(仅在应用程序更改时调用,需要在 DB 存储过程中处理)

insert into [SensorStateChange_History] (SensorIndex, SensorOccupied, TimeOfDataBaseStorage)
values (@SensorIndex, @SensorOccupied, GETUTCDATE())

update SensorState_Latest
set SensorOccupied = @SensorOccupied, 
    TimeOfDataBaseStorage = GETUTCDATE()
and SensorIndex = @SensorIndex

if @@ROWCOUNT = 0

insert into SensorState_Latest
values (@SensorIndex, @SensorOccupied, GETUTCDATE())

【问题讨论】:

  • 这里的问题是什么?您发布的内容应该可以正常工作。
  • 每次调用存储过程时都会在表中存储一个值。我希望存储过程仅在值与最新值不同时才存储历史记录
  • 那么你只需要在更新中添加额外的条件。
  • 什么额外条件?返回之前的值?
  • 在更新语句中添加一个额外的谓词。我假设您的意思是sensoroccuied的值?只需添加“And SensorOccupied @SensorOccupied”或您想知道它是否更改的任何值。

标签: sql sql-server stored-procedures database-design


【解决方案1】:

我会这样做:

IF NOT EXISTS(SELECT * FROM [SensorStateChange_Latest] WHERE SensorIndex=@SensorIndex AND SensorOccupied=@SensorOccupied)
  BEGIN
  update SensorState_Latest
  set SensorOccupied = @SensorOccupied, 
    TimeOfDataBaseStorage = GETUTCDATE()
  WHERE SensorIndex = @SensorIndex;    

  if @@ROWCOUNT = 0    
    insert into SensorState_Latest
    values (@SensorIndex, @SensorOccupied, GETUTCDATE())

  insert into [SensorStateChange_History] (SensorIndex, SensorOccupied, TimeOfDataBaseStorage)
  values (@SensorIndex, @SensorOccupied, GETUTCDATE());

  END

【讨论】:

  • 这是有道理的。为了提高性能,有没有办法消除第一个选择语句并利用更新语句来更新/检索旧值?那么您不必访问数据库来查找值然后更新它吗?
  • 实际上,我相信 IF EXISTS() 的执行速度会比您建议的要快。谷歌并了解 EXISTS() 函数,你就会明白我所说的性能优势。
  • blogs.msdn.com/b/miah/archive/2008/02/17/… 我不同意……如果它不存在,则只有 1 次表扫描,如果确实存在,则它至少有 2 次表扫描。我想问题归结为如何利用更新来始终更新最新值并返回其先前的值...这将导致始终进行单个表扫描并在之后访问先前和当前值更新
  • 好吧,我想这是一个有效的学术问题,但我的答案是“我会怎么做”。
  • 如果您真的想最小化您的表扫描,您可以在触发器中执行此操作。然后插入和删除的虚拟表将具有“之前”和“之后”值。不过,我会像这个答案一样编写代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 2018-10-04
相关资源
最近更新 更多