Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

МиСПрИС_Задание2_4_Петрова_Романова_Заболотников_9373

.pdf
Скачиваний:
19
Добавлен:
20.06.2023
Размер:
1.31 Mб
Скачать

Выводы.

В ходе данной работы был разработан проект каркаса для работы со спецификациями изделий с вариантами исполнения. После проведённых тестов работоспособности программы убедились, что все функции – функции формирования параметров конфигурации, функции формирования варианта исполнения, функции формирования спецификации варианта исполнения – работают корректно. Также выяснили, что процедура расчёта сводных норм расхода материальных ресурсов варианта исполнения работает без ошибок.

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