选择自上次SELECT以来已更改的所有内容

时间:2013-06-12 06:57:41

标签: sql-server

暂不考虑better ways从SQL服务器获取“表差异” - 假设我有一个UpdTime列类型为datetime的表,这是在每次插入和更新时使用getdate()进行设置和更新,如下所示:

UPDATE mytable SET Updtime=getdate(), ... WHERE ...
INSERT INTO mytable VALUES (getdate(),...)

初步

之后
SELECT getdate() AS Now, ... FROM mytable WITH(readcommitted,rowlock)

我曾经读过所有行并将Now的值存储在变量lastNow中,然后我继续做期刊

SELECT getdate() AS Now, ... FROM mytable WITH(readcommitted,rowlock) WHERE UpdTime >= lastNow;

调用,始终将新Now存储到我的lastNow变量中。

我能确定永远不会错过任何更改(显然除了DELETE)吗?或者这取决于某些设置?

顺便说一下,看到两次变化并没有打扰我,只会错过一次改变。

修改我刚刚将WITH(readcommitted,rowlock)添加到上面的SELECT语句中,因为我想要添加“diff”功能的旧语句看起来像

2 个答案:

答案 0 :(得分:1)

getdate()runtime constant function,意味着它被评估一次,并且在整个语句中使用相同的值。

readcommitted语句的默认UPDATE级别,肯定有可能开始并评估GETDATE(),然后开始SELECT语句并获得更晚GETDATE()语句在UPDATE完成所有行更新之前的值。

如果SELECT以不同于UPDATE的顺序定位行(可能两个使用不同的索引访问方法),或者UPDATE在计划中有阻塞运算符(例如,对于万圣节保护),SELECT可以在行更新之前读取行。然后,在下一个请求中不会读取这些行,因为他们将收到的最终Updtime小于lastNow值。

如果UPDATE计划要包含阻止运算符,那么甚至可以在serializable下进行此操作。

答案 1 :(得分:0)

我不确定你的问题是什么,因为“我能确定永远不会错过任何更改(显然除了DELETE)吗?或者这取决于某些(事务性?)设置?”似乎暗示如果做出改变(然后回滚)你想看到它?我不确定你是否想看看是否已经做出改变?

除非您的选择包含'read dirty'提示,否则您将看不到更改。如果是这样,您将看到所有已提交的更改和所有未经注释的更改,但不会显示已回滚的更改,因为它们不再存在。对于read dirty,您将获得返回的原始和未提交(更新)行。

使用getdate()的另一个方面是它的粒度低至1000秒,这曾经没问题,但是对于现代并行处理器,很有可能获得具有相同GetDate()值的多个更新。