SQL中检查行是否已更新的最佳方法

8

我有一个更新语句,用于更新一个表。其中有一列记录最后修改时间。如果特定行的数据没有被更改,我就不想更改最后修改日期时间。

如何检查更新语句是否会更改数据行。

谢谢。

8个回答

9

在代码中检查旧数据和新数据,而不是在查询中进行。

如果数据没有发生变化,就没有必要无谓地打扰数据库层。

简而言之,如果数据没有发生变化,就不要发送UPDATE语句。


虽然如此,有些情况下你可能被迫执行一个先前的查询(SELECT)来获取数据,然后再执行第二个查询来进行实际的更新 - 在这种情况下,即使没有更改发生,我可能只会执行单个UPDATE查询。 - J.C. Inacio
我同意@jcinacio的观点,但如果我们采用@jcinacio的方法,OP的问题仍然存在。 因此,如果OP正在使用sql 2005/2008,则可以使用OUTPUT子句来比较新值和旧值。请参阅下面的我的答案。 - IsmailS

2

一种方法是启动一个事务,选择行的内容并将其与要更新的内容进行比较。如果它们不匹配,则执行更新并结束事务。如果它们匹配,则回滚事务。


2
听起来你正在遍历一个表格并修改一些行,然后你想再次遍历这个表格,并更新刚刚被改变的行的时间戳。
不要分成两步来做。在修改其他列的同时,同时更新日期/时间:
UPDATE myTable
SET retailprice = wholesaleprice * 1.10,
    lastmodified = GetDate()
WHERE ...

你是不是在对所有行发出更新语句,但对于大多数行,它只是将其设置为已有的值?不要这样做。在where子句中排除那些不会被修改的行:

UPDATE myTable
SET retailprice = wholesaleprice * 1.10,
    lastmodified = GetDate()
WHERE retailprice <> wholesaleprice * 1.10

1
如果您想要预防性地执行此操作,我能想到的唯一方法是修改更新语句的 WHERE 子句,将现有值与新值进行比较(对于每个值)。如果任何一个值不相等,则应执行更新。

1

这就是使用数据访问层(DAL)的好处。它可以跟踪所有列,因此如果没有更改,则不会向数据库发送更新语句。


1

这取决于您是否控制数据。Seb上面说的很正确,您应该在更新之前检查旧数据和新数据。但是如果数据不受您的控制怎么办?

假设您是一个被要求进行更新的webservice。那么唯一的检查方式就是查询现有数据并将其与新数据进行比较。

不知道有任何SQL功能可以检测更新是否实际更改了任何数据。

在SQL中有一些方法可以检测更新语句中包含了多少行。不知道有没有一种检测更新语句实际更改了任何数据的方法,这很有趣。


1
如果您正在使用 SQL 2005/2008,则可以在存储过程中按照以下方式操作。
update  newTable 
set     readKey='1'
output  inserted.id,
        inserted.readKey as readKey,
        deleted.readKey as prevReadKey
into @tempTable
where id = '1111'

然后,您可以从@tempTable中选择以验证prevReadKey和readKey是否具有相似的值,如果两者具有相似的值,则可以重置上次修改的日期时间。

这样,在实际值发生更改的情况下,您就不必在表上触发多个查询。但是,在值不变的情况下,这将触发两个更新语句,其中没有一个是必需的。如果这些情况很少出现,那么这应该是可以接受的。

P.S. 注意:- 给出的查询可能在语法上有误,因为它没有经过测试。但是,这是解决您的问题的方法。我在我的一个项目中使用了Merge语句的OUTPUT子句来完成它,也可以使用update语句完成。这里是OUTPUT Clause的参考资料


0

您可以在 T-SQL 中编写一个 INSTEAD OF UPDATE 触发器,在其中执行 DAL 层中建议的操作 - 比较现有记录中的值与更新语句中的值,然后应用更新或不进行更新。您可以在触发器中使用 Columns_Updated() 函数来查看是否已更新任何内容,并相应地进行处理。

从机器的角度来看,这并不特别高效,但您只需编写一次代码,它就可以处理此情况,无论哪个应用程序、存储过程或其他进程尝试更新记录。


你是如何知道这是一个 SQL Server 的设置,是因为历史记录还是之前的问题? - James Piggot
你说得对 - 我不知道。我做了一个假设。然而,其他SQL数据库(例如Oracle)也实现了类似的功能。不确定mySQL、Postgres或类似的数据库是否有这个功能。 - Rob Schripsema

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接