带有无效查询的数据库表损坏:它做了什么并将回滚?

时间:2011-06-15 21:44:26

标签: sql sql-server data-warehouse

我犯了错误,运行应该对我的事实表(200M行)进行快速更新:

update dbo.primary_fact
   set count_of_loan_obligors = o.n              
  from dbo.staging_fact f  
       -- notice that this is not the same table as the one in the update clause
       inner join ##Obligor_Count o
       on (f.time_dimension_id = o.time_dimension_id
           and f.account_dimension_id = o.account_dimension_id)

应该是:

  from dbo.primary_fact f

像这样正确形成的更新(1天,87k帐户)通常在一分钟或2分钟结束。运行12分钟后,我想知道这么长时间内发现了我的错误。

我在SQL Server Management Studio中取消了这个查询,据我所知,它会回滚我造成的所有可怕的错误(有人可以确认吗?)

但我的更大问题是:错误形成的查询有什么作用?


更新:取消操作最终完成,一小时39分钟后。 DBA在杀戮上的速度太慢 - 同样也是如此。

正确形成的更新在8秒内完成。

第二次更新:在SSMS中成功取消订单后,原始(错误)更新中未设置任何值。我会解释这意味着任何挂起的更新都会被回滚。

3 个答案:

答案 0 :(得分:5)

  

但我更大的问题是:什么呢   错误形成的查询吗?

它将使用相同的值更新dbo.primary_fact.count_of_loan_obligors所有行。该值将是##Obligor_Count.n的某个值。很难弄清楚会是什么价值。

这是一个基本上做你所做的小测试:

declare @T1 table (ID int)
declare @T2 table (ID int)

insert into @T1 values (0)
insert into @T1 values (0)

insert into @T2 values (2)
insert into @T2 values (1)

update @T1
set ID = T2.ID
from @T2 as T2

select *
from @T1

结果:

ID
2
2

在这种情况下,使用@T1中的第一行更新@T2

答案 1 :(得分:3)

好吧,首先看起来你可能只是用正确的from子句而不是staging_fact表重新运行你的查询,它会覆盖你所做的任何booboos。这是好消息,也是使用事实表的乐趣。

坏消息是,根据我的经验,除非您在事务中实际运行SSMS,否则SSMS不会回滚任何内容,因此您的数据现在可能是一大堆失败。

希望你享受生命的最后12分钟,因为你将有幸再次这样做。

答案 2 :(得分:2)

我担心这两个版本都没有做任何好事,因为它们都缺少一个WHERE子句,它将正在更新的表与新值的源(f inner join o)连接起来。我希望在复制/粘贴中删除行WHERE primary_fact.time_dimension_id=f.time_dimension_id AND primary_fact.account_dimension_id=f.account_dimension_id

只要引用的表中包含这些名称的列,fo的连接就会很好。然后这些值将用于更新primary_fact,或者使用WHERE子句,或者以某种方式我不知道。 UPDATE / FROM语法不是标准SQL,但它受到广泛支持。也许SQL SERVER甚至添加了默认的WHERE子句。 Postgresql没有。