0

SQL Server にストアド プロシージャがあります。Delphi から実行すると、デッドロック メッセージが表示されます。

トランザクション (プロセス 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 で機能しますが、これを Delphi から実行すると、デッドロック メッセージが再度表示されます。これは私のクエリがどのように見えるかです:

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

Delphiでは、次のコードでコマンドを実行します。

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

2 に答える 2

4

シリアライズ可能なトランザクションでラップする必要があります

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

さらに、テーブルを空にするtruncate代わりにon を使用できる場合があり、ユーザー テーブルの代わりにローカル一時テーブル ( ) またはテーブル変数 ( ) を使用できます。drop#Stocksss@Stocksss

于 2013-09-21T17:28:14.530 に答える
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

ありがとうございました!

于 2013-09-22T21:53:40.427 に答える