Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
6 сем / 1 / преподское / Пример_оформления _Зад_1_1.docx
Скачиваний:
3
Добавлен:
29.03.2025
Размер:
1.86 Mб
Скачать

1.5. Разработка основных процедур

/***************************************************************************/

create procedure DEL_EI(pIdEI integer)

returns(oRes integer)

/*функция: Удаление ед. измерения

вход: pIdEI - ид. ЕИ

выход: oRes - 0 - удаление невозможно, 1 - удаление выполнено

эффекты:

*/

create or alter procedure DEL_ENUM (

PIDENUM integer)

returns (

ORES integer)

as

declare variable VYES integer;

begin

/*функция: Удаление перечисления*/

select count(*)

from PARAMETR

where TYPE_PAR = :PIDENUM

into :VYES;

if (:VYES = 0) then

begin

delete from ENUM

where ID_ENUM = :PIDENUM;

ORES = 1;

end

else

ORES = 0;

suspend;

end

/***************************************************************************/

/***************************************************************************/

create procedure INS_EI(pCode varchar(15),pShName varchar(10),pName varchar(50))

returns(oIdEI integer, oRes integer)

/*функция: Добавление новой единицы измерения

вход: pCode - международный код ЕИ;

pShName - обозначение;

pName - имя ЕИ

выход:oIdEI - Ид. новой ЕИ;

oRes - результат завершения 0 - ошибка, 1 – успешно

эффекты:

*/

create or alter procedure INS_EI (

PCODE varchar(15),

PSHNAME varchar(10),

PNAME varchar(50))

returns (

OIDEI integer,

ORES integer)

as

begin

oRes=1;

select oNew from GEN_ID_EI

into :oIdEI;

insert into EI(ID_EI,SHORT_NAME,NAME,CODE)

values(:oIdEI,:pShName,:pName,:pCode);

suspend;

end

/************************************************************************/

Процедуры для работы с классификатором.

Необходима процедура:

FIND_LIST должна найти список продукции заданного класса

Требуется разработать вспомогательную процедуру:

FIND_TERM_GR – должна найти все терминальные группы заданной группы.

Требуется найти все группы заданной группы:

FIND_GR_GR.

Начнем с последней процедуры:

/*******************************************************************************/

create or alter procedure FIND_GR_GR (

PIDGR integer)

returns (

OIDGR integer,

ONAMEGR varchar(100),

OSHORTNAMEGR varchar(15),

OTERM integer)

as

declare variable VCOUNTGR integer;

declare variable VIDGR integer;

begin

/*функция:

1. Выдает элементы дерева в порядке вложенности

вход:

pIdGr - ид. исходной группы

выход:

oIdGr - ид. группы

oNameGr - имя группы

oShortNameGr - обозначение группы

oTerm - 0 - нетерминал, 1 - терминал

эффекты:

1. Для терминального элемента выдает исходный элемент

2. Исходный элемент всегда первый в списке

требования:

1. Элемент должен быть в исходном дереве

*/

vCountGr=0; /*начальная инициализация*/

oTerm=0;

oIdGr=0;

$$IBE$$*/ /*является ли исходная группа терминальной*/ /*$$IBE$$

select count(*) from CHEM_CLASS

where MAIN_CLASS=:pIdGr

into :vCountGr;

if (:vCountGr=0) then

begin

oIdGr=pIdGr;

oTerm=1;

select NAME,SHORT_NAME from CHEM_CLASS

where ID_CLASS=:oIdGr

into :oNameGr,:oShortNameGr;

suspend;

end

else /*найти входящие группы*/

begin

vIdGr=0;

oTerm=0;

select NAME,SHORT_NAME from CHEM_CLASS

where ID_CLASS=:pIdGr

into :oNameGr,:oShortNameGr;

oIdGr=pIdGr;

suspend;

for select ID_CLASS from CHEM_CLASS

where MAIN_CLASS=:pIdGr

into :vIdGr

do

begin

for select oIdGr, oNameGr, oShortNameGr,oTerm from FIND_GR_GR(:vIdGr)

into :oIdGr,:oNameGr,:oShortNameGr,:oTerm

do

suspend;

end

end

end

/*******************************************************************************/

Вторая процедура не нужна – это простой запрос:

for select oIdGr, oNameGr, oShortNameGr,oTerm from FIND_GR_GR(:pIdGr)

where oTerm=1

into :oIdGr,:oNameGr,:oShortNameGr,:oTerm

do …..

/************************************************************************/

create procedure FIND_LIST (PIDGR integer)

returns (

OIDEL integer,

ONAME varchar(200) character set WIN1251,

OSHORTNAME varchar(50) character set WIN1251,

ONAMEEI varchar(50) character set WIN1251)

as

declare variable VEI integer;

declare variable VIDGR integer;

begin

/*функция: Найти список номенклатурных единиц заданной группы

вход:PIDGR - ид. класса

выход: OIDEL - ид. продукции,

ONAME - имя продукции,

OSHORTNAME обозначение продукции,

ONAMEEI - имя ЕИ

эффекты:

*/

vIdGr=0;

for select oIdGr from FIND_GR_GR(:pIdGr)

where oTerm=1

into :vIdGr

do

begin

oIdEl=0;

oName='';

oShortName='';

select BASE_EI from CHEM_CLASS

where ID_CLASS=:vIdGr

into :vEI;

select SHORT_NAME from EI

where ID_EI=:vEI

into :oNameEI;

for select ID_PROD,NAME,SHORT_NAME from PROD

where ID_CL=:vIdGr

into :oIdEl,:oName,:oShortName do

begin

suspend;

end

end

end

Дополнительно потребуется следующая процедура:

/**************************************************************************/

create or alter procedure IN_GR1 (

PMAINGR integer,

PGR integer)

returns (

OYES integer)

as

BEGIN

/*функция:

Проверяет принадлежность pGR к pMainGR

вход:

pMainGR - Код Главной группы

pGR - код проверяемой группы

выход:

oYes - 0 - не принадлежит, 1 - принадлежит

редактор:

25.10.2012 Дубенецкий В.А.

*/

/*инициализация переменных */

oYes=0;

select count(*) from FIND_GR_GR(:pMainGR)

where oIdGr=:pGr

into :oYes;

suspend;

end

/**************************************************************************/

create procedure DEL_CLASS(pIdClass integer)

returns(oRes integer)

as

declare variable vYes integer;

begin

/*функция: Удаление класса из схемы

вход: pIdClass - ид. класса

выход: oRes - результат выполнения 0 - удаление невозможно, 1 - удаление выполнено

*/

select count(*) from FIND_LIST(:pIdClass)

into vYes;

oRes=0;

if (:vYes=0) then

begin

delete from CHEM_CLASS

where ID_CLASS=:pIdClass;

oRes=1;

end

suspend;

end

/*******************************************************************************/

/*************** Процедура создания нового продукта ****************/

create procedure INS_PROD(pIdClass integer,pShName varchar(15),pName varchar(100))

returns(oIdProd integer,oRes integer)

as

DECLARE VARIABLE vYesClass INTEGER;

DECLARE VARIABLE vYesTerm INTEGER;

begin

oRes=0;

select count(*) from CHEM_CLASS

where ID_CLASS=:pIdClass

into :vYesClass;

if(:vYesClass =1) then

begin

select count(*) from CHEM_CLASS

where MAIN_CLASS=:pIdClass

into :vYesTerm;

if(:vYesTerm=0) then

begin

oRes=1;

select oNew from GEN_ID_PROD

into :oIdProd;

insert into PROD(ID_PROD,SHORT_NAME,NAME,ID_CL)

values(:oIdProd,:pShName,:pName,:pIdClass);

select oRes from COPY_PAR_PROD(:oIdProd)

into :oRes;

end

end

suspend;

end

/*******************************************************************************/

/************************************************************************/

create or alter procedure YES_CIRCLE (

PIDEL integer)

returns (

OYESCIRCLE integer)

as

BEGIN

/*функция:

Проверяет спецификацию на наличие циклов

вход:

pIdEl - Код элемента, для которого ведется расчет

выход:

oYesCircle - 0 - циклов нет, > 0 - циклы есть

*/

update SPEC_PROD

set FLAG=0

where FLAG >0;

select count(*) from FIND_CIRCLE(:pIdEl,0)

where oYesCircle>0

into :oYesCircle;

suspend;

END

/*******************************************************************************/

/*******************************************************************************/

create or alter procedure FIND_CIRCLE (

PIDEL integer,

PYESCIRCLE integer)

returns (

OYESCIRCLE integer,

OIDEL1 integer,

OIDEL2 integer)

as

declare variable VINEL integer;

declare variable VY integer;

declare variable VYESCIRCLE integer;

begin

/*функция: Проверяет наличие циклов и выводит проверенные пары вершин и индикатор цикла

вход: pIdEl - ид. начальной вершины

pYesCircle - индикатор наличия цикла (при вызове =0)

выход: oYesCircle - индикатор наличия цикла (0 - цикла нет),

oIdEl1 - ид. используемого элемента,

oIdEl2 - ид. использующего элемента

эффекты:

1. При обнаружении хотя бы одного цикла oYesCircle сохраняет значение > 0 для всех остальных проверок

требования:

1. При начальном вызове установить pYesCircle = 0

*/

if(:pYesCircle=0) then

begin

oYesCircle=pYesCircle;

vYesCircle=0;

/*Для всех непосредственнх неотмеченных связей элемента pIdEl*/

for select p1.USE_EL, p1.FLAG from SPEC_PROD p1

where p1.ID_PROD=:pIdEl and p1.FLAG<>1

into :vInEl,:vY do

begin

/*Помечаем текущую связь */

update SPEC_PROD p4

set p4.FLAG=1

where p4.ID_PROD=:pIdEl and p4.USE_EL=:vInEl;

/*Проверяем наличие обратной связи*/

select count(*) from SPEC_PROD p2

where ( p2.ID_PROD=:vInEl and p2.USE_EL=:pIdEl)

into :vYesCircle;

/*Помечаем обратную связь*/

if(:vYesCircle >0) then

begin

oYesCircle=1;

update SPEC_PROD p4

set p4.FLAG=1

where p4.ID_PROD=:vInEl and p4.USE_EL=:pIdEl;

end

/*присваиваем значения выходным параметрам и вывод*/

oIdEl1=vInEl;

oIdEl2=pIdEl;

suspend;

/*Для всех связей текущего элемента рекурсивно выполняем данную процедуру*/

for select oYesCircle,oIdEl1,oIdEl2

from FIND_CIRCLE(:vInEl,:oYesCircle)

into :vYesCircle,:oIdEl1,:oIdEl2

do

begin

suspend;

if(:vYesCircle=0) then

begin

/*Проверяем связи найденной вершины с исходной (циклы длины > 1)*/

select count(*) from SPEC_PROD p3

where ( p3.ID_PROD=:oIdEl1

and p3.USE_EL=:pIdEl)

into :vYesCircle;

if(:vYesCircle>0) then

begin

/*Помечаем текущую связь */

update SPEC_PROD p4

set p4.FLAG=1

where p4.ID_PROD=:oIdEl1

and p4.USE_EL=:pIdEl;

oYesCircle=1;

oIdEl2=pIdEl;

suspend;

end

end

else

oYesCircle=1;

end

end

end

end

/*******************************************************************************/