暂不考虑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”功能的旧语句看起来像
答案 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()值的多个更新。