Problem – opis

Update jednej tabeli wartościami drugiej. Dwie tabele niżej przedstawione są częścią większego systemu, który służy między innymi do rejestracji czasu zawodników  na maratonie rowerowym.

Dane – opis

W tabeli tag_number przechowywane są numer identyfikacyjne tag-ów oraz ich etykiety które są naniesione fizycznie na dyskietkę (tag). Zawodnik otrzymuje taką dyskietkę by identyfikować się na punktach pomiaru czasu.


Tabela Zawodnik łączy kartotekę zarejestrowanych i opłaconych zawodników z tagiem (dyskietką) oraz listą startową, w tym momencie lista nie ma znaczenia.
Uczestnik zarejestrowany w systemie nie staje się zawodnikiem, zawodnikiem staje się tylko wtedy kiedy opłaci udział. W tym momencie uczestnik przepisywany jest do tabeli zawodnik i przydzielany jest mu pierwszy wolny numer.

Rozwiązanie – opis

Do rozwiązania tego problemu użyłem updata wywoływanego w pętli while oraz to samo rozwiązanie w kursorze (dla porównania). Dlaczego pętla lub kursor gdyż rzadkością będzie przepisywanie jednego uczestnika, częściej będzie ich większa ilość.

Poniższy kod dostępny na Github.

declare @licznik int = 1
declare @ilosc int
select @ilosc = count( zaw_id) from participant.Zawodnik
where
zaw_aktywny = 1 and tag_id is null
while ( @licznik <= @ilosc)
begin
UPDATE participant.Zawodnik
SET
tag_id = (
select top 1 TN2.tag_id from participant.Tag_Number TN2
left join participant.Zawodnik ZP on ZP.tag_id = TN2.tag_id
where
ZP.tag_id is null
)
from participant.Tag_Number TG
where
zaw_id = (select top 1 ZZ.zaw_id from participant.Zawodnik ZZ
where ZZ.tag_id is null)
and Zawodnik.tag_id is null
end;

Poniżej to samo ale na kursorze.

declare @zaw_id int;
declare @tag_id int
declare c1 Cursor For
select @zaw_id,@tag_id from participant.Zawodnik
where
zaw_aktywny = 1 and tag_id is null
Open c1;
Fetch Next From c1 Into @zaw_id, @tag_id;
While @@FETCH_STATUS = 0 –
Begin
UPDATE participant.Zawodnik
SET
tag_id = (
select top 1 TN2.tag_id from participant.Tag_Number TN2
left join participant.Zawodnik ZP on ZP.tag_id = TN2.tag_id
where
ZP.tag_id is null
)
from participant.Tag_Number TG
where
zaw_id = (select top 1 ZZ.zaw_id from participant.Zawodnik ZZ
where ZZ.tag_id is null)
and Zawodnik.tag_id is null
Fetch Next From c1 Into @zaw_id,@tag_id;
End
Close c1;
DeAllocate c1;

1 Komentarz

Marcin · Luty 27, 2019 o 6:00 am

to sie nie klei

Możliwość dodawania komentarzy nie jest dostępna.