在 sql server 2008R2 中错误更新语句后如何回滚?

Vin*_* _S 5 sql-server sql-server-2008-r2

select * from aa

update aa set City='chennai',LastName='vinoth';

ID  FirstName  LastName  City
29  Abcrdrr    vinoth    chennai
1   John       vinoth    chennai
2   Joe        vinoth    chennai
35  raja       vinoth    chennai
38  Johsdfgn   vinoth    chennai
Run Code Online (Sandbox Code Playgroud)

我错误地更新Lastname, City了所有行中的列。现在我想回滚到旧的表行。

使用 SQL Server 2008R2。

Bla*_*ler 16

除非您有某种历史记录表和触发器,以便在每次更改时保留旧值,或者您在运行更新之前制作了该表的副本,否则您将需要使用在该更新之前进行的最后一次备份。恢复它(作为一些临时数据库)并提取数据。
您确实有可用的备份,对吗?

顺便说一句,下次您进行更新时,我建议您这样设置:

SELECT *
-- UPDATE t SET Column1 = x, Column2 = y
FROM MyTable AS t
WHERE ...
Run Code Online (Sandbox Code Playgroud)

运行第SELECT一个以准确查看将更新哪些行。如果需要,调整WHERE子句以获取要定位的行。然后才从头到尾标记句子UPDATE并执行它。比运行“盲目”更新要安全得多,就像您所做的那样,忘记了该WHERE条款(我认为这是问题所在)。
更安全 - 先在一些测试数据库上做:)。


Kin*_*hah 13

另一种方法是用于fn_dblog检查事务日志。这是一个安静的高级主题,因此可以参考一篇出色的文章How to read and interpret the SQL Server log - by Remus Rusanu

为避免将来,您始终可以使用 Transactions

BEGIN TRAN
BEGIN TRY
  update tbl set City='chennai',LastName='vinoth' from aa AS tbl;

  -- if update is what you want then
  COMMIT TRAN
END TRY
BEGIN CATCH
  -- if NOT then
  IF @@TRANCOUNT > 0
      ROLLBACK
  THROW
END CATCH
Run Code Online (Sandbox Code Playgroud)

编辑:在编写复杂的 T-SQL 时,您应该使用一个TRY-CATCH块 withTRANSACTION以便在发生异常或查询被取消时不会锁定资源。否则,如果查询不复杂,最好不要使用事务。

此外,正如 Blaz 所提到的,在对数据库进行任何更改之前备份数据库或仅备份表总是好的。