МиСПрИС_Задание2_4_Петрова_Романова_Заболотников_9373
.pdfВыводы.
В ходе данной работы был разработан проект каркаса для работы со спецификациями изделий с вариантами исполнения. После проведённых тестов работоспособности программы убедились, что все функции – функции формирования параметров конфигурации, функции формирования варианта исполнения, функции формирования спецификации варианта исполнения – работают корректно. Также выяснили, что процедура расчёта сводных норм расхода материальных ресурсов варианта исполнения работает без ошибок.
21
ПРИЛОЖЕНИЕ А
----------------------------------------------------------------------
Таблицы
----------------------------------------------------------------------
create table Rules --Таблица правил
(
id_function serial not null primary key,-- id правила function_name text not null -- имя правила
)
create table Spec_Product --Таблица позиций спецификатора
(
id_pair serial not null primary key,-- id пары главного продукта и используемого
id_mainProduct integer not null, -- id главного продукта id_useProduct integer not null, --id составного продукта pos_inSp integer not null, -- Номер позиции
q_inSp integer not null, -- Количество используемого продукта в главном
id_function integer,-- id_правила flag integer not null,
CONSTRAINT id_mainProduct FOREIGN KEY (id_mainProduct) REFERENCES Product (id_product) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
)
create unique index union_MainAndUse on Spec_Product(id_mainProduct, id_useProduct); --Создадим индекс для уникальности пар (главный продукт,
составной продукт)
ALTER TABLE Spec_Product ADD CONSTRAINT id_useProduct FOREIGN KEY (id_useProduct)
REFERENCES public.Product (id_product) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE cascade;
22
ALTER TABLE Spec_Product ADD CONSTRAINT id_function FOREIGN KEY (id_function)
REFERENCES public.Rules (id_function) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE cascade
CREATE TABLE PREDICAT (
id_pred serial not null primary key, id_param integer not null,
id_value integer not null, oper text not null,
CONSTRAINT id_value FOREIGN KEY (id_value)
REFERENCES enum_value (id_value) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
);
ALTER TABLE PREDICAT ADD CONSTRAINT id_param FOREIGN KEY (id_param) REFERENCES public.Parameters (id_param) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE cascade;
CREATE TABLE BODY_FUNC (
id_pair serial not null primary key, id_func integer not null,
id_pred integer not null, num_dis integer not null, num_con integer not null,
CONSTRAINT id_func FOREIGN KEY (id_func)
REFERENCES Rules (id_function) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
);
ALTER TABLE BODY_FUNC ADD CONSTRAINT id_pred FOREIGN KEY (id_pred) REFERENCES public.PREDICAT (id_pred) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE cascade;
23
----------------------------------------------------------------------
Дополненные сопровождающие функции
----------------------------------------------------------------------
/*******************************************************SPEC_PRODUCT**
**********************************************************************
********/
-- Проверка на цикл
CREATE OR REPLACE function check_loop (
spIdToCheck integer) RETURNS table (id_useproduct int) LANGUAGE plpgsql as $func$
begin
RETURN QUERY
with recursive graph(id_mainproduct, id_useproduct, path) as ( select sp.id_mainproduct, sp.id_useproduct, CAST (sp.id_useproduct
AS TEXT) as PATH
from spec_product as sp where sp.id_mainproduct = spIdToCheck union all
select spec_product.id_mainproduct, spec_product.id_useproduct, CAST ( graph.PATH ||' = > '|| spec_product.id_useproduct AS TEXT)
from spec_product inner join graph on graph.id_useproduct = spec_product.id_mainproduct
where spec_product.id_mainproduct <> spIdToCheck
)
select graph.id_useproduct from graph where graph.id_useproduct = spIdToCheck limit 1;
end $func$;
-- Добавление элементов в таблицу SP
/*функция: Дообавляет новую позицию в спецификатор и поверяет не создано ли циклов. Если циклы есть, то изменения откатываются
вход: id_mainProductN - ид. продукта главного id_useProductN - ид. используемого продукта
countInSPN -количество используемого продукта flagN - флаг базы
эффекты:
24
1.Если продукта главного или используемого не существует, то будет выведена ошибка.
2.Если при поощи новой позиции был создан цикл, то изменения не будут внесены.
3.Позиция пары будет вычислена автоматически
*/
CREATE OR REPLACE function add_posSP ( id_mainProductN integer, id_useProductN integer, countInSPN integer,
idFunc integer,
flagN integer) RETURNS VOID as $$
declare ind_mp int default 0; declare ind_up int default 0; declare posNew int default 0; begin
select id_product from product where id_mainProductN = id_product into ind_mp;
select id_product from product where id_useProductN = id_product into ind_up;
if (ind_mp is not null) then if ind_up is not null then
select max(pos_inSP)+1 from spec_product where id_mainProductN = id_mainproduct into posNew;
if posNew is null then posNew:= 1;
end if;
INSERT INTO spec_product(id_mainproduct, id_useproduct,pos_inSP,q_inSP,id_function, flag) VALUES (id_mainProductN, id_useProductN,posNew,countInSPN,idFunc, flagN);
if check_loop(id_mainProductN) is not null then
delete from spec_product where id_mainproduct = id_mainProductN and id_useproduct = id_useProductN;
raise exception 'You have created the loop. Db was
not updated.';
end if;
25
else
raise exception 'This using product is not existing. Db was not updated.';
end if; else
raise exception 'This main product is not existing. Db was not updated.';
end if;
end $$ LANGUAGE plpgsql;
--Удаление Позиции в спецификаторе
/*функция: Удаляет ппозицию в спецификаторе, если заявленный идентификато пары существует
вход: spIdToDelete - id_variation пары, которую нужно удалить эффекты:
1. Если id пары нет, то будет выведено сообщение об ошибке.
*/
CREATE OR REPLACE function delete_sp ( spIdToDelete integer) RETURNS VOID
as $$ begin
if(select id_pair from spec_product where spIdToDelete = id_pair limit 1) is not null then
DELETE FROM spec_product WHERE spIdToDelete = id_pair;
else
raise exception 'SP with this id does not exist. DB wasnt
updated.'; end if;
end $$ LANGUAGE plpgsql;
/*******************************************************************RU
LE********************************************************************
****/
CREATE OR REPLACE function add_rule (pName text) returns table(oIdF integer,oRes integer)
as $$
DECLARE vYesF INTEGER;
26
begin
/*функция: Создает новую функцию без тела вход:pShName - обозначение
pName - имя
выход: oIdF - ид. новой функции
oRes - 0 - ошибка 1 - функция сформирована эффекты: */
oRes=1;
select id_function from Rules where function_name = pNAME into vYesF; if(vYesF>0) then oRes=0;
else
insert into rules (function_name)
values(pName) returning id_function into oIdF; oRes=1;
end if; return NEXT;
end $$ LANGUAGE plpgsql;
--Удаление правила
CREATE OR REPLACE function delete_rule (
IdToDelete integer) RETURNS VOID
as $$
/*функция: Удаление элемента из таблицы rules
вход: IdToDelete - ид. правила, которое нужно удалить выход: 1 - БД обновлена, 0 - Ошибка эффекты: 1. Проверка на существование удаляемой записи
*/ begin
if(select id_function from rules where IdToDelete = id_function) is not null then
DELETE FROM rules WHERE IdToDelete = id_function;
else
raise exception 'Rule with this id does not exist. DB wasnt
updated.'; end if;
end $$ LANGUAGE plpgsql;
27
/**************************************************************PREDICA
TE********************************************************************
***/
CREATE OR REPLACE function add_predicat(pIdPar integer,pOper text,pVal integer)
returns table(oIdPred integer,oRes integer) as $$
DECLARE vYesPar INTEGER;
DECLARE vYesVal INTEGER; begin
/*функция: Создает новый предикат вход:pIdPar - ид.параметра
pOper - оператор '=', '>', '<' pVal - ид. значения
выход: oIdPred - ид. нового продукта
oRes - 0 - ошибка 1 - предикат сформирован эффекты: */
oRes=1;
--Найдем, если указанные пользователем ид. значения и параметра в БД select id_param from parameters where id_param = pIdPar into vYesPar; select id_value from enum_value where id_value = pVal into vYesVal; if (((pOper = '=') or (pOper='>')or(pOper='<')) and (vYesPar>0) and
(vYesVal>0)) then --Если введённые значения удовлетворяют условиямм, то oRes=1;
insert into predicat (id_param,oper,id_value) values (pIdPar,pOper,pVal) returning id_pred into oIdPred;
else oIdPred=0; oRes=0;
end if; return next;
end $$ LANGUAGE plpgsql;
--Удаление предикат
CREATE OR REPLACE function delete_predicat (
IdToDelete integer) RETURNS VOID
as $$
/*функция: Удаление элемента из таблицы predicat
28
вход: IdToDelete - ид. правила, которое нужно удалить выход: 1 - БД обновлена, 0 - Ошибка эффекты: 1. Проверка на существование удаляемой записи
*/ begin
if(select id_pred from predicat where IdToDelete = id_pred) is not null then
DELETE FROM predicat WHERE IdToDelete = id_pred;
else
raise exception 'Predicat with this id does not exist. DB wasnt updated.';
end if;
end $$ LANGUAGE plpgsql; /*************************************************************BODY_FUN
**********************************************************************
***/
CREATE OR REPLACE function add_predInBody(pIdF integer,pNumD integer, pIdPred integer)
returns table(oNumK integer,oRes integer) as $$
DECLARE vYesF INTEGER;
DECLARE vYesPred INTEGER;
DECLARE vYesNumD INTEGER;
DECLARE vMaxNumK INTEGER;
begin
/*функция: Добавляет в функцию новый предикат вход:pIdF - ид.фуекции
pNumD - номер дизъюнкции pIdPred - ид. предиката
выход: oNumK - номер конъюнкции oRes - 0 - ошибка 1 - предикат сформирован эффекты: */
oRes=1;
select id_function from rules where id_function = pIdF into vYesF; select id_pred from predicat where id_pred = pIdPred into vYesPred;
29
if((vYesF>0)and(vYesPred>0)) then --Если введённые предикат и правило существуют
select id_func from body_func where id_func = pIdF and num_dis = pNumD into vYesNumD;
if(vYesNumD>0)then
select MAX(num_con) from body_func where id_func = pIdF and num_dis = pNumD into vMaxNumK;
if( vMaxNumK is null) then vMaxNumK=1;
else vMaxNumK=vMaxNumK+1; end if;
else vMaxNumK=1;
end if;
insert into body_func (id_func,num_dis ,num_con ,id_pred) values(pIdF,pNumD,vMaxNumK,pIdPred);
oRes=1;
oNumK=vMaxNumK;
else oRes=0;
return next; end if;
end $$ LANGUAGE plpgsql;
--Удаление предиката из правила
CREATE OR REPLACE function delete_predInBody (
IdToDelete integer) RETURNS VOID
as $$
/*функция: Удаление элемента из таблицы body_func
вход: IdToDelete - ид. правила, которое нужно удалить выход: 1 - БД обновлена, 0 - Ошибка эффекты: 1. Проверка на существование удаляемой записи
*/ begin
if(select id_pair from body_func where IdToDelete = id_pair) is not null then
30