2013-09-21 49 views
0

我在SQL Server中有一个存储过程。当我从德尔福执行它时,我得到一个死锁消息!存储过程中的死锁

事务(进程ID 60)被死锁的锁|通用等待对象资源与另一个进程并被选为死锁牺牲品

我应该在下面的查询中更改以解决这种情况。我的存储过程没有参数。

ALTER PROCEDURE [dbo].[RepairStocks] 
AS 
BEGIN 
    SET NOCOUNT ON; 

    drop table [dbo].[stocksss] 

    select 
     Barkod, 
     sum(kolicina) as Kolicina, 
     Max(Kategorija) as Kategorija, 
     Max(Artikal) as Artikal, 
     Max(Opis) as Opis, 
     Max(N_cena) as N_cena, 
     Max(N_cena) * sum(kolicina) as N_Iznos, 
     Max(P_cena) as P_cena, 
     Max(P_Cena) * sum(kolicina) as P_Iznos, 
     Max(datum) as datum, 
     Max(Golemina) as Golemina 
    into [dbo].[stocksss] 
    from [dbo].[Stocks] 
    group by Barkod 

    drop table [dbo].[Stocks]; 

    select * 
    into [dbo].[Stocks] 
    from [dbo].[stocksss] 

END 

任何帮助深表感谢......

编辑我查询后

下面的查询工作SQL Server上,但是我又得到了僵局消息时,我从德尔福执行此。这是我的查询的外观:

ALTER PROCEDURE [dbo].[RepairStocks] 

AS 
BEGIN 

SET NOCOUNT ON; 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 

BEGIN TRAN 

select 
Barkod, 
sum(kolicina) as Kolicina, 
Max(Kategorija) as Kategorija, 
Max(Artikal) as Artikal, 
Max(Opis) as Opis, 
Max(N_cena) as N_cena, 
Max(N_cena) * sum(kolicina) as N_Iznos, 
Max(P_cena) as P_cena, 
Max(P_Cena) * sum(kolicina) as P_Iznos, 
Max(datum) as datum, 
Max(Golemina) as Golemina 


into #tmp_stocks 
from [dbo].[Stocks] 
group by Barkod 
-------------------------------- 
; 
DROP TABLE [dbo].[Stocks] 
; 
-------------------------------- 


select * 
into [dbo].[Stocks] 
from #tmp_stocks with (nolock) 
; 
drop table #tmp_stocks 
; 

COMMIT TRAN 

END 

德尔福我执行命令,用下面的代码:

RepairStocks.Close; 
RepairStocks.SQL.Clear; 
RepairStocks.SQL.Add('EXEC [dbo].[RepairStocks]'); 
RepairStocks.ExecSQL; 
+2

尝试(NOLOCK)'。确保'Barkod'被编入索引。使用本地临时表和单个事务(如答案中的建议)与'LEVEL SNAPSHOT'一起使用。 – kobik

+0

你使用什么组件? tadoquery? tsqlquery? – whosrdaddy

回答

4

你应该在一个串行事务包裹它

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
BEGIN TRAN 
    ... 
COMMIT TRAN 

另外,您可以使用truncate,而不是drop在桌子清空后,你可以使用本地临时表( #Stocksss)或表变量(@Stocksss)而不是用户表

+0

我 SET事务隔离级别尝试SERIALIZABLE BEGIN TRAN ... COMMIT TRAN 我也用临时表(#tmp_Stocks)它的工作原理好于SQL Management Studio中。当我在Delphi上执行它时,我用不同的ID再次发生死锁错误 – Barlet

0

也许这不是最好的方式,但它对我有效,我得到我应该得到的结果。 此外,当我在Delphi

@podiluska执行这个我没有得到任何错误 - 你的建议在SQL Server Management Studio的工作

ALTER PROCEDURE [dbo].[RepairStocks] 
AS 
BEGIN 

begin tran 

delete from stocksss 


--insert from Stocks to Stocksss 
INSERT INTO stocksss 
select Barkod, 
sum(kolicina) as Kolicina, 
Max(Kategorija) as Kategorija, 
Max(Artikal) as Artikal, 
Max(Opis) as Opis, 
Max(N_cena) as N_cena, 
Max(N_cena) * sum(kolicina) as N_Iznos, 
Max(P_cena) as P_cena, 
Max(P_Cena) * sum(kolicina) as P_Iznos, 
Max(datum) as datum, 
Max(Golemina) as Golemina 
from [dbo].[Stocks] 
group by Barkod 
; 

---------------------------------------------------------- 

delete from Stocks 

insert into Stocks 
select * from stocksss 
; 

Commit Tran 

END 

谢谢!使用'与(NOLOCK)`暗示即`...从[DBO] [股票]与