Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

SQL Threadsafe UPDATE TOP 1 pour la file d'attente FIFO

Mon problème serait de dupliquer [InvoiceID]
Plusieurs demandes d'impression pour le même [InvoiceID]

Lors de la première mise à jour, UNE ligne obtient set [Status] = 'Printing'

Lors de la deuxième mise à jour, toutes les lignes [InvoiceID] obtiennent set [Status] = 'Printed'
Cela définirait même des lignes avec status ='draft'

C'est peut-être ce que vous voulez

Un autre processus pourrait récupérer le même [InvoiceID] avant que le set [Status] = 'Print'

Ainsi, certains doublons s'imprimeront et d'autres non

Je vais avec des commentaires sur l'utilisation du update lock

Ceci n'est pas déterministe mais vous pouvez simplement prendre top (1) et ignorez le order by . Vous aurez tendance à obtenir la ligne la plus récente, mais ce n'est pas garanti. Si vous effacez la file d'attente, vous les obtenez tous.

Cela démontre que vous pouvez perdre 'brouillon' =1

declare @invID int; 
declare @T table (iden int identity primary key, invID int, status tinyint);
insert into @T values (1, 2), (5, 1), (3, 1), (4, 1), (4, 2), (2, 1), (1, 1), (5, 2), (5, 2);
declare @iden int;
select * from @t order by iden;

declare @rowcount int = 1; 
while (@ROWCOUNT > 0)
    begin
        update top (1) t 
        set t.status = 3, @invID = t.invID,  @iden = t.iden
        from @t t 
        where t.status = '2';
        set @rowcount = @@ROWCOUNT;
        if(@rowcount > 0)
            begin 
                select @invID, @iden;
                -- do stuff  
                update t 
                set t.status = 4
                from @t t
                where t.invID = @invID; -- t.iden = @iden;
                select * from @T order by iden;
            end
    end