Procedura - sprawdzenie i przeliczanie wartości w każdym wierszu

0

Cześć,
mam problem/zagwozdkę czy poniższy kod da się przerobić w jakiś sensowny sposób aby tak dziwnie nie sprawdzać ID w pętli. Nie przychodzi mi nic do głowy na ten moment a podczas update-u wiersza muszę z niego pobrać 2 wartości, sięgnąć do innej tabeli i na ich podstawie obliczyć i wstawić ilość urlopu.

Po testach procedura działa w taki sposób jak bym chciał (oczywiście po obwarowaniu checkami i trrigerami nie pojawiają się błędy że któreś podzapytanie zwraca kilka wierszy/wartości).

Pozdrawiam

screenshot-20210507221603.png


CREATE OR ALTER PROCEDURE prox.PR_coroczny_urlop_wypoczynkowy
AS
	BEGIN
		DECLARE @temporary_id int;
		DECLARE @urlop_wypoczynkowy int;
		DECLARE @staz int;
		DECLARE @etacik float;
		DECLARE @MAX_ID int;

		SET @MAX_ID = (SELECT MAX(IDzatrudnienia) from prox.okres_zatrudnienia);
		SET @temporary_id = 0;

		WHILE (@temporary_id < @MAX_ID)
			BEGIN
			SET @temporary_id = @temporary_id + 1;
			DECLARE @ID_PR int = (SELECT DISTINCT IDpracownika FROM prox.okres_zatrudnienia WHERE IDzatrudnienia = @temporary_id);
			DECLARE @zatr_od date = (SELECT zatrudniony_od FROM prox.okres_zatrudnienia
									WHERE zatrudniony_do IS NULL AND IDpracownika = @ID_PR);
		

			DECLARE @okr_zatr float;
		
			SET @okr_zatr = (DATEDIFF(MONTH, @zatr_od, DATEFROMPARTS(YEAR(GETDATE()), 12, 31)))/12.0;

			SET @staz =		(SELECT staz_pracy FROM prox.okres_zatrudnienia
							WHERE zatrudniony_do IS NULL AND IDpracownika = @ID_PR);
			SET @etacik =	(SELECT WCP.etat FROM prox.okres_zatrudnienia AS OZ inner join wymiar_czasu_pracy as WCP ON OZ.IDwymiar=WCP.IDwymiar
							WHERE zatrudniony_do IS NULL AND IDpracownika = @ID_PR);
	
			IF (@staz) = 0
				BEGIN
					SET @urlop_wypoczynkowy  = CEILING(20 * @etacik * @okr_zatr);
					UPDATE prox.okres_zatrudnienia SET nalezny_urlop = @urlop_wypoczynkowy
					WHERE zatrudniony_do IS NULL AND IDpracownika = @ID_PR
				END

			IF (@staz) = 1
				BEGIN
					SET @urlop_wypoczynkowy = CEILING(26 * @etacik * @okr_zatr);
					UPDATE prox.okres_zatrudnienia SET nalezny_urlop = @urlop_wypoczynkowy
					WHERE zatrudniony_do IS NULL AND IDpracownika = @ID_PR
				END
			END
	END
GO


1

Zgodzę się z @AnyKtokolwiek logika w bazie to proszenie się o klopoty.

Co do samej procedury to skoro aktualizujesz wszystkie rekordy to po co ci pętla, mozna to zrobić np. tak:

UPDATE 
	prox.okres_zatrudnienia 
SET 
	nalezny_urlop = CEILING(case when staz_pracy = 1 then 26 else 20 end * WCP.etat * (DATEDIFF(MONTH,  zatrudniony_od, DATEFROMPARTS(YEAR(GETDATE()), 12, 31)))/12.0);
from
	prox.okres_zatrudnienia  AS OZ 
	inner join wymiar_czasu_pracy as WCP ON OZ.IDwymiar=WCP.IDwymiar
WHERE 
	zatrudniony_do IS NULL

1 użytkowników online, w tym zalogowanych: 0, gości: 1