
- •Задание на работу
- •1.1. Разработать проект каркаса для работы со спецификациями изделий
- •1.2. Содержание работы
- •1.3. Исходные данные для задачи
- •1.4. Рекомендуемые инструменты
- •1.5. Рекомендуемые источники
- •Аннотация
- •1. Описание выполненной работы
- •1.1. Анализ исходных данных
- •1.2. Разработка функциональных требований к подсистеме
- •1.3. Разработка модели классов
- •1.4. Разработка модели хранения в среде субд данных классификатора изделий
- •1. Разработка erd
- •2. Создание базы данных
- •3. Подготовка скриптов метаданных
- •1.5. Разработка основных процедур
- •1.6. Тестирование разработки
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
/*******************************************************************************/