diff --git a/Lab/Lab#6/lab6_done.sql b/Lab/Lab#6/lab6_done.sql index b79b71a..e4827dd 100644 --- a/Lab/Lab#6/lab6_done.sql +++ b/Lab/Lab#6/lab6_done.sql @@ -9,24 +9,82 @@ b) Напишите программу на языке PL/SQL, печатающ и имя сотрудника с идентификатором 1 и всех его подчинённых, как прямых, так и подчинённых более низкого ранга. */ -CREATE OR REPLACE PROCEDURE department_names() AS $$ -DECLARE d_attrs RECORD; +-- CREATE OR REPLACE PROCEDURE department_names() AS $$ +-- DECLARE d_attrs RECORD; +-- BEGIN + +-- FOR d_attrs IN WITH RECURSIVE tmp AS ( +-- SELECT id, first_name, last_name, manager_id, 1 AS level +-- FROM bd6_employees +-- WHERE manager_id = 1 or id = 1 +-- UNION ALL +-- SELECT e.id, e.first_name, e.last_name, e.manager_id, t.level + 1 +-- FROM bd6_employees e JOIN tmp t ON e.manager_id = t.id ) + +-- SELECT * FROM tmp +-- LOOP +-- RAISE INFO ' % % ', d_attrs.first_name, d_attrs.last_name; +-- END LOOP; +-- END $$ LANGUAGE plpgsql; +-- CALL department_names(); + +-- Пункт а) +WITH RECURSIVE tmp AS ( +SELECT id, first_name, last_name, manager_id, 1 AS level +FROM bd6_employees +WHERE manager_id = 1 or id = 1 +UNION ALL +SELECT e.id, e.first_name, e.last_name, e.manager_id, t.level + 1 +FROM bd6_employees e JOIN tmp t ON e.manager_id = t.id ) + +SELECT * FROM tmp + +-- Пункт б) +CREATE OR REPLACE PROCEDURE department_names(integer) AS $$ +DECLARE + d_attrs RECORD; + i integer; + l integer; BEGIN - -FOR d_attrs IN WITH RECURSIVE tmp AS ( - SELECT id, first_name, last_name, manager_id, 1 AS level - FROM bd6_employees - WHERE manager_id = 1 or id = 1 - UNION ALL - SELECT e.id, e.first_name, e.last_name, e.manager_id, t.level + 1 - FROM bd6_employees e JOIN tmp t ON e.manager_id = t.id ) - -SELECT * FROM tmp -LOOP - RAISE INFO ' % % ', d_attrs.first_name, d_attrs.last_name; -END LOOP; +FOR d_attrs IN + ( + SELECT id,last_name, first_name, manager_id + FROM bd6_employees + ORDER BY manager_id + ) + LOOP + IF d_attrs.manager_id=$1 THEN + RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id; + l:= d_attrs.id; + CALL department_names(l); + END IF; + END LOOP; END $$ LANGUAGE plpgsql; -CALL department_names(); + + +CREATE OR REPLACE PROCEDURE department_names2(integer) AS $$ +DECLARE + d_attrs RECORD; + BEGIN + FOR d_attrs IN + ( + SELECT + id, + last_name, + first_name, + manager_id + FROM bd6_employees + ORDER BY manager_id + ) + + LOOP + IF d_attrs.id=$1 THEN + RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id; + END IF; + END LOOP; +CALL department_names($1); +END $$ LANGUAGE plpgsql; +CALL department_names2(4); -- Task 2 -- @@ -60,6 +118,32 @@ LOOP m_salary := ((current_salary + mod_salary) / 100) * 100; END IF; +RAISE NOTICE 'Employee: % % || Modified Salary: %', employee_rec.last_name, employee_rec.first_name, m_salary; +END LOOP; +END $$ LANGUAGE plpgsql; + +CALL print_employees(); +CREATE OR REPLACE PROCEDURE print_employees() AS $$ +DECLARE +current_salary INTEGER; +m_salary INTEGER; +mod_salary INTEGER := 0; +employee_rec RECORD; +BEGIN +FOR employee_rec IN ( + SELECT last_name, first_name, salary_in_euro + FROM bd6_employees + ORDER BY salary_in_euro) + +LOOP + current_salary := employee_rec.salary_in_euro; + + IF mod_salary=0 THEN + m_salary := (current_salary / 100) * 100; + ELSE + m_salary := ((current_salary + mod_salary) / 100) * 100; +END IF; + RAISE NOTICE 'Employee: % %, Modified Salary: %', employee_rec.last_name, employee_rec.first_name, m_salary; mod_salary := current_salary - m_salary; END LOOP; @@ -140,4 +224,35 @@ then RAISE INFO ' % % % % %', d_attrs.f5, d_attrs.f4, d_attrs.f3, d_attrs.f2, d_ end case; END LOOP; END $$ LANGUAGE plpgsql; -call f(); \ No newline at end of file +call f(); + +-- Task 7 from lab4 -- + + + + + + +CREATE OR REPLACE PROCEDURE department_names(integer) AS $$DECLARE d_attrs RECORD; +i integer;l integer; +BEGIN +FOR d_attrs IN ( SELECT id,last_name, first_name, manager_id + FROM bd6_employees order by manager_id ) + LOOP + if d_attrs.manager_id=$1 then + RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id; l:= d_attrs.id; + call department_names(l); end if; +END LOOP; +END $$ LANGUAGE plpgsql; + + +CREATE OR REPLACE PROCEDURE department_names2(integer) AS $$ +DECLARE d_attrs RECORD; +BEGINFOR d_attrs IN ( + SELECT id,last_name, first_name, manager_id FROM bd6_employees order by manager_id ) + +LOOP + if d_attrs.id=$1 then RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id; + end if;END LOOP; +CALL department_names($1);END $$ LANGUAGE plpgsql; +CALL department_names2(4); \ No newline at end of file diff --git a/Lab/Lab#6/test3.sql b/Lab/Lab#6/test3.sql index 40cf955..78bdae3 100644 --- a/Lab/Lab#6/test3.sql +++ b/Lab/Lab#6/test3.sql @@ -33,4 +33,40 @@ BEGIN END LOOP; END; $$ LANGUAGE plpgsql; -SELECT rearrange_salaries(); \ No newline at end of file +SELECT rearrange_salaries(); + + + + +CREATE OR REPLACE FUNCTION update_salaries() RETURNS VOID AS $$ +DECLARE + max_salary_employee_id INTEGER; + min_salaries numeric[]; + max_salaries numeric[]; + i INTEGER; + const CONSTANT INTEGER = 10; +BEGIN + -- Получаем заработные платы последних 10 человек с самой маленькой заработной платой + SELECT array_agg(id) FROM bd6_employees + ORDER BY salary_in_euro ASC + LIMIT const INTO min_salaries; + + -- Получаем заработные платы 10 первых человек с самой большой заработной платой + SELECT array_agg(id) FROM bd6_employees + ORDER BY salary_in_euro DESC + LIMIT const INTO max_salaries; + + -- Добавляем заработные платы + FOR i IN 1..const LOOP + UPDATE bd6_employees + SET salary_in_euro = salary_in_euro + min_salaries[i] + WHERE id = max_salaries[i]; + END LOOP; + + -- Удаляем 10 человек с наименьшей заработной платой + DELETE FROM bd6_employees + WHERE id IN (SELECT unnest(min_salaries)); + + RAISE NOTICE 'Заработные платы обновлены и % человек удалены', const; +END; +$$ LANGUAGE plpgsql; \ No newline at end of file