You don't show what the data looks like before the update so I had to guess a little.
No need for PL/SQL. Straight SQL should work.
See if this works for you:
merge into tab1 t1
using(
select empid, salary_rt, row_number() over(partition by empid order by eff_dt desc) rn
from tab1
) t2
on (t1.empid=t2.empid and t1.salary_rt=t2.salary_rt)
when matched then update
set
t1.end_dt=case when rn=1 then to_date('12/31/9999','MM/DD/YYYY') else t1.end_dt end,
t1.valid=case when rn=1 then 'Y' else 'N' end
/
It assumes empid and salary_rt are distinct. If not, you'll need to change the columns in the 'ON' clause of the MERGE.
Using eff_dt instead of salary_rt:
merge into tab1 t1
using(
select empid, eff_dt, row_number() over(partition by empid order by eff_dt desc) rn
from tab1
) t2
on (t1.empid=t2.empid and t1.eff_dt=t2.eff_dt)
when matched then update
set
t1.end_dt=case when rn=1 then to_date('12/31/9999','MM/DD/YYYY') else t1.end_dt end,
t1.valid=case when rn=1 then 'Y' else 'N' end
/
100 abc 10/05/2014 10/05/2014 06/04/2015 N
100 lmn 06/04/2015 06/04/2015 05/10/2019 N
100 pqr 05/10/2019 05/10/2019 null Y
200 lkd 04/02/2018 04/02/2018 05/20/2019 N
200 fjk 05/20/2019 05/20/2019 null Y
Should it not be like this?