Приведение наименований в менеджере — различия между версиями
Материал из wiki.standart-n.ru
Aleksnick (обсуждение | вклад) (Новая страница: «Устанавливаем процедуру '''PR_GET_WARE'''. <pre> SET TERM ^ ; create or alter procedure PR_INSTALL_PR_GET_WARE as declare variable IDX_U_EX…») |
Aleksnick (обсуждение | вклад) |
||
| (не показано 5 промежуточных версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
| + | =Алгоритм работы приведения с Единым Окном= | ||
| + | ==Этап 1: Открытие электронной накладной== | ||
| + | При открытии накладной срабатывает процедура '''PR_MAKEGOODWAREVALUES'''. | ||
| + | * Вначале неё по каждому полю (sname, sizg, scountry, sorig_name, sorig_izg, sorig_country) ищем id значений из таблицы vals. | ||
| + | <pre> | ||
| + | select id from vals where vtype=0 and alttype=:alttype and svalue=:sname into :name_id; | ||
| + | ... | ||
| + | </pre> | ||
| + | * Затем вызывается процедура '''PR_GETWARE_BY_IDS''' | ||
| + | <pre> | ||
| + | select ware_id from PR_GETWARE_BY_IDS(:name_id,:izg_id,:country_id,:orig_code,:orig_name_id,:orig_izg_id,:orig_country_id,0,1, :barcode) into :ware_id; | ||
| + | </pre> | ||
| + | * В данной процедуре идет поиск карточки товара по реальным полям в таблице связок wares_log. | ||
| + | <pre> | ||
| + | select first 1 iif(actual_ware_id is null, id, actual_ware_id) from wares_log where name_id=:name_id and izg_id=:izg_id and country_id=:country_id and barcode=:barcode | ||
| + | order by log_insertdt desc | ||
| + | </pre> | ||
| + | '''1. В таблице wares_log есть записи с одинаковыми реальными полями, но они ссылаются на разные товары, а сортировка по log_insertdt неправильна, т.к. это поле не везде заполнено.'''<br> | ||
| + | '''2. Вроде бы записи с actual_ware_id должны удаляться.'''<br> | ||
| + | '''3. Есть записи, которые ни по id ни по actual_ware_id не ссылаются на существующий варес.''' | ||
| + | <pre> | ||
| + | select min(iif(wl.actual_ware_id is null, wl.id, wl.actual_ware_id)), max(iif(wl.actual_ware_id is null, wl.id, wl.actual_ware_id)) | ||
| + | from wares_log wl | ||
| + | group by wl.name_id, wl.izg_id, wl.country_id, wl.barcode | ||
| + | having count(iif(wl.actual_ware_id is null, wl.id, wl.actual_ware_id))>1 | ||
| + | </pre> | ||
| + | * Если мы нашли готовую карточку товара, в связках, то затем находим ее в таблице wares и берем все ее значения. После чего выходим из процедуры: | ||
| + | <pre> | ||
| + | if (ware_id is not null) then | ||
| + | begin | ||
| + | select sname, sizg, scountry, barcode from VW_WARES where id=:ware_id into :goodname, :goodizg, :goodcountry, :goodbarcode; | ||
| + | if (goodname is null) then goodname = sname; | ||
| + | ... | ||
| + | exit; | ||
| + | end | ||
| + | </pre> | ||
| + | * Если готовую карточку не нашли, то снова пытаемся ее найти, вызывая процедуру '''PR_GETWARE_BY_IDS''', но уже с параметром searchinlogs=null | ||
| + | <pre> | ||
| + | select ware_id from PR_GETWARE_BY_IDS(:name_id,:izg_id,:country_id,:orig_code,:orig_name_id,:orig_izg_id,:orig_country_id,0,null, :barcode) into :ware_id; | ||
| + | </pre> | ||
| + | '''4. ЗАЧЕМ??? Все карточки должны быть в wares_log!!!''' | ||
| + | * Если всетаки нашлась карточка, то берем из нее реальные поля: | ||
| + | <pre> | ||
| + | if (ware_id is not null) then | ||
| + | begin | ||
| + | goodname=sname; | ||
| + | goodizg=sizg; | ||
| + | goodcountry=scountry; | ||
| + | goodbarcode=barcode; | ||
| + | suspend; | ||
| + | exit; | ||
| + | end | ||
| + | </pre> | ||
| + | * Затем пытаемся отдельно привести каждое из реальных полей. | ||
| + | ** Если есть оригинальное значение, то ищем первую попавшуюся карточку товара с данным значением: | ||
| + | <pre> | ||
| + | select first 1 id from wares where orig_name_id=:orig_name_id order by id desc into :ware_id; | ||
| + | </pre> | ||
| + | '''5. Зачем??? В таблице wares оригинальные поля вообще не будут актуальными!!!''' | ||
| + | ** Если не нашли, то приводим значение через связки: | ||
| + | <pre> | ||
| + | if (ware_id is null) then | ||
| + | select first 1 iif(actual_ware_id is null, id, actual_ware_id) from wares_log where orig_name_id=:orig_name_id order by log_id desc into :ware_id; | ||
| + | </pre> | ||
| + | '''6. Поле log_id имеет тип d$uuid - связка может найтись не самая актуальная.''' | ||
| + | * Если мы ничего не нашли, то ищем по реальному полю. Точно также: сначала в таблице wares, затем wares_log. | ||
| + | <pre> | ||
| + | if ((ware_id is null) and (name_id is not null)) then | ||
| + | begin | ||
| + | select first 1 id from wares where name_id=:name_id into :ware_id; | ||
| + | if (ware_id is null) then | ||
| + | select first 1 iif(actual_ware_id is null, id, actual_ware_id) from wares_log where name_id=:name_id order by log_id desc into :ware_id; | ||
| + | end | ||
| + | </pre> | ||
| + | '''7. Почему бы сразу не искать в таблице wares_log???''' | ||
| + | ** Затем точно также делаем по изготовителю и стране. | ||
| + | * Возвращаем полученные значения. | ||
| + | |||
| + | ==Этап 2: Проведение активного документа== | ||
| + | На каждый товар срабатывает процедура '''PR_GET_WARE'''. | ||
| + | * Берутся и при необходимости создаются справочные значения для всех реальных и оригинальных полей: | ||
| + | <pre> | ||
| + | select VAL_ID from PR_GETVAL_ID(:SNAME, 0, :ALTTYPE, :MNN) into :NAME_ID; | ||
| + | ... | ||
| + | </pre> | ||
| + | * Идет поиск карточки товара по реальным полям: | ||
| + | <pre> | ||
| + | select ID from WARES where NAME_ID = :NAME_ID and IZG_ID = :IZG_ID and COUNTRY_ID = :COUNTRY_ID and BARCODE = :BARCODE into :W_ID; | ||
| + | </pre> | ||
| + | * Если карточка нашлась, то выходим из процедуры, иначе создаем новую карточку: | ||
| + | <pre> | ||
| + | if (W_ID is null) then | ||
| + | begin | ||
| + | W_ID = uuid_to_char(gen_uuid()); | ||
| + | insert into WARES (ID, NAME_ID, IZG_ID, COUNTRY_ID, ORIG_CODE, ORIG_NAME_ID, ORIG_IZG_ID, ORIG_COUNTRY_ID, BARCODE, Z_ID, SKLAD_ID) | ||
| + | values (:W_ID, :NAME_ID, :IZG_ID, :COUNTRY_ID, :ORIG_CODE, :ORIG_NAME_ID, :ORIG_IZG_ID, :ORIG_COUNTRY_ID, :BARCODE, :Z_ID, :SKLAD_ID); | ||
| + | end | ||
| + | suspend; | ||
| + | </pre> | ||
| + | |||
| + | |||
| + | =Установка процедур= | ||
| + | |||
Устанавливаем процедуру '''PR_GET_WARE'''. | Устанавливаем процедуру '''PR_GET_WARE'''. | ||
<pre> | <pre> | ||
| Строка 12: | Строка 115: | ||
declare variable FIELD DM_TEXT; | declare variable FIELD DM_TEXT; | ||
begin | begin | ||
| − | + | /* определяем база с глобальными наименованиями или нет */ | |
if ((select upper(RF.RDB$FIELD_SOURCE) | if ((select upper(RF.RDB$FIELD_SOURCE) | ||
from RDB$RELATION_FIELDS RF | from RDB$RELATION_FIELDS RF | ||
| Строка 22: | Строка 125: | ||
GLOBAL_ID = 0; | GLOBAL_ID = 0; | ||
| + | /* определяем единое окно установлено или нет */ | ||
if ((select first 1 count(1) | if ((select first 1 count(1) | ||
from RDB$INDICES RIN | from RDB$INDICES RIN | ||
| Строка 30: | Строка 134: | ||
IDX_U_EXISTS = 0; | IDX_U_EXISTS = 0; | ||
| + | /* определяем из какого индекса брать список полей, отвечающих за уникальность товаров */ | ||
if (IDX_U_EXISTS = 1) then | if (IDX_U_EXISTS = 1) then | ||
INDEX_NAME = 'WARES_IDX_U'; | INDEX_NAME = 'WARES_IDX_U'; | ||
| Строка 35: | Строка 140: | ||
INDEX_NAME = 'WARES_IDX1'; | INDEX_NAME = 'WARES_IDX1'; | ||
| + | /* определяем установлен ли хэш индекс */ | ||
if ((select first 1 count(1) | if ((select first 1 count(1) | ||
from RDB$INDICES RIN | from RDB$INDICES RIN | ||
| Строка 43: | Строка 149: | ||
IDX_100_EXISTS = 0; | IDX_100_EXISTS = 0; | ||
| + | /* входные параметры процедуры */ | ||
S = ' | S = ' | ||
create or alter procedure PR_GET_WARE ( | create or alter procedure PR_GET_WARE ( | ||
| Строка 60: | Строка 167: | ||
'; | '; | ||
| + | /* выходные параметры процедуры */ | ||
if (GLOBAL_ID = 1) then | if (GLOBAL_ID = 1) then | ||
S = S || 'W_ID type of DM_UUID_NULL)'; | S = S || 'W_ID type of DM_UUID_NULL)'; | ||
| Строка 65: | Строка 173: | ||
S = S || 'W_ID type of DM_ID)'; | S = S || 'W_ID type of DM_ID)'; | ||
| + | /* внутренние параметры процедуры */ | ||
S = S || ' as | S = S || ' as | ||
declare variable OLD_BARCODE DM_TEXT1024;'; | declare variable OLD_BARCODE DM_TEXT1024;'; | ||
| + | /* для базы с глобальными наименованиями типы полей DM_UUID_NULL */ | ||
if (GLOBAL_ID = 1) then | if (GLOBAL_ID = 1) then | ||
S = S || ' | S = S || ' | ||
| Строка 81: | Строка 191: | ||
| + | /* для базы без глобальных наименований типы полей DM_ID */ | ||
S = S || ' | S = S || ' | ||
declare variable NAME_ID type of DM_ID; | declare variable NAME_ID type of DM_ID; | ||
| Строка 95: | Строка 206: | ||
'; | '; | ||
| + | /* вставляем в процедуру комментарии */ | ||
if (GLOBAL_ID = 1) then | if (GLOBAL_ID = 1) then | ||
S = S || ' /* BASE WITH GLOBAL ID */ | S = S || ' /* BASE WITH GLOBAL ID */ | ||
| Строка 116: | Строка 228: | ||
'; | '; | ||
| + | /* находим валсы для всех справочных значений */ | ||
S = S || ' if (ORIG_CODE is null) then | S = S || ' if (ORIG_CODE is null) then | ||
ORIG_CODE = ''''; | ORIG_CODE = ''''; | ||
| Строка 138: | Строка 251: | ||
'; | '; | ||
| + | /* если хэш индекса нет */ | ||
if (IDX_100_EXISTS = 0) then | if (IDX_100_EXISTS = 0) then | ||
| Строка 150: | Строка 264: | ||
'; | '; | ||
| + | /* ищем варес по всем поляем, которые есть в индексе, отвечающем за уникальность карточек */ | ||
select list('and ' || trim(RIS.RDB$FIELD_NAME) || ' = :' || trim(RIS.RDB$FIELD_NAME), ascii_char(13)) | select list('and ' || trim(RIS.RDB$FIELD_NAME) || ' = :' || trim(RIS.RDB$FIELD_NAME), ascii_char(13)) | ||
from RDB$INDEX_SEGMENTS RIS | from RDB$INDEX_SEGMENTS RIS | ||
| Строка 158: | Строка 273: | ||
into :W_ID, | into :W_ID, | ||
:OLD_BARCODE; | :OLD_BARCODE; | ||
| − | + | '; | |
| − | + | ||
| − | + | ||
end | end | ||
| Строка 167: | Строка 280: | ||
| + | /* если хэш индекс есть в базе */ | ||
begin | begin | ||
| Строка 172: | Строка 286: | ||
whash = ('; | whash = ('; | ||
| − | select list(':' || trim(RIS.RDB$FIELD_NAME), ',') | + | /* генерируем хэш по поляем в индексе */ |
| + | select list('coalesce(:' || trim(RIS.RDB$FIELD_NAME) || ',''' || trim(RIS.RDB$FIELD_NAME) || ''')', ',') | ||
from RDB$INDEX_SEGMENTS RIS | from RDB$INDEX_SEGMENTS RIS | ||
where RIS.RDB$INDEX_NAME = :INDEX_NAME | where RIS.RDB$INDEX_NAME = :INDEX_NAME | ||
| Строка 179: | Строка 294: | ||
S = S || :FIELD || ');'; | S = S || :FIELD || ');'; | ||
| + | /* ищем варес по хэшу */ | ||
S = S || ' | S = S || ' | ||
select ID, | select ID, | ||
| Строка 187: | Строка 303: | ||
:OLD_BARCODE; | :OLD_BARCODE; | ||
'; | '; | ||
| − | |||
end | end | ||
| + | /* если варес не нашли */ | ||
| + | S = S || ' | ||
| + | if (W_ID is null) then | ||
| + | begin | ||
| + | '; | ||
| + | |||
| + | /* генерируем id */ | ||
if (GLOBAL_ID = 1) then | if (GLOBAL_ID = 1) then | ||
S = S || ' W_ID = uuid_to_char(gen_uuid()); | S = S || ' W_ID = uuid_to_char(gen_uuid()); | ||
| Строка 198: | Строка 320: | ||
'; | '; | ||
| + | /* создаем новый варес */ | ||
S = S || ' insert into WARES (ID, NAME_ID, IZG_ID, COUNTRY_ID, ORIG_CODE, ORIG_NAME_ID, ORIG_IZG_ID, ORIG_COUNTRY_ID, | S = S || ' insert into WARES (ID, NAME_ID, IZG_ID, COUNTRY_ID, ORIG_CODE, ORIG_NAME_ID, ORIG_IZG_ID, ORIG_COUNTRY_ID, | ||
BARCODE, Z_ID, SKLAD_ID) | BARCODE, Z_ID, SKLAD_ID) | ||
| Строка 204: | Строка 327: | ||
end | end | ||
else | else | ||
| + | '; | ||
| + | |||
| + | /* если штрихкод не в индексе */ | ||
| + | S = S || ' | ||
if (OLD_BARCODE <> BARCODE) then | if (OLD_BARCODE <> BARCODE) then | ||
update WARES | update WARES | ||
| Строка 224: | Строка 351: | ||
GRANT EXECUTE ON PROCEDURE PR_INSTALL_PR_GET_WARE TO SYSDBA; | GRANT EXECUTE ON PROCEDURE PR_INSTALL_PR_GET_WARE TO SYSDBA; | ||
| + | |||
EXECUTE PROCEDURE PR_INSTALL_PR_GET_WARE; | EXECUTE PROCEDURE PR_INSTALL_PR_GET_WARE; | ||
DROP PROCEDURE PR_INSTALL_PR_GET_WARE; | DROP PROCEDURE PR_INSTALL_PR_GET_WARE; | ||
</pre> | </pre> | ||
Текущая версия на 10:53, 16 августа 2016
Содержание
Алгоритм работы приведения с Единым Окном
Этап 1: Открытие электронной накладной
При открытии накладной срабатывает процедура PR_MAKEGOODWAREVALUES.
- Вначале неё по каждому полю (sname, sizg, scountry, sorig_name, sorig_izg, sorig_country) ищем id значений из таблицы vals.
select id from vals where vtype=0 and alttype=:alttype and svalue=:sname into :name_id; ...
- Затем вызывается процедура PR_GETWARE_BY_IDS
select ware_id from PR_GETWARE_BY_IDS(:name_id,:izg_id,:country_id,:orig_code,:orig_name_id,:orig_izg_id,:orig_country_id,0,1, :barcode) into :ware_id;
- В данной процедуре идет поиск карточки товара по реальным полям в таблице связок wares_log.
select first 1 iif(actual_ware_id is null, id, actual_ware_id) from wares_log where name_id=:name_id and izg_id=:izg_id and country_id=:country_id and barcode=:barcode order by log_insertdt desc
1. В таблице wares_log есть записи с одинаковыми реальными полями, но они ссылаются на разные товары, а сортировка по log_insertdt неправильна, т.к. это поле не везде заполнено.
2. Вроде бы записи с actual_ware_id должны удаляться.
3. Есть записи, которые ни по id ни по actual_ware_id не ссылаются на существующий варес.
select min(iif(wl.actual_ware_id is null, wl.id, wl.actual_ware_id)), max(iif(wl.actual_ware_id is null, wl.id, wl.actual_ware_id)) from wares_log wl group by wl.name_id, wl.izg_id, wl.country_id, wl.barcode having count(iif(wl.actual_ware_id is null, wl.id, wl.actual_ware_id))>1
- Если мы нашли готовую карточку товара, в связках, то затем находим ее в таблице wares и берем все ее значения. После чего выходим из процедуры:
if (ware_id is not null) then
begin
select sname, sizg, scountry, barcode from VW_WARES where id=:ware_id into :goodname, :goodizg, :goodcountry, :goodbarcode;
if (goodname is null) then goodname = sname;
...
exit;
end
- Если готовую карточку не нашли, то снова пытаемся ее найти, вызывая процедуру PR_GETWARE_BY_IDS, но уже с параметром searchinlogs=null
select ware_id from PR_GETWARE_BY_IDS(:name_id,:izg_id,:country_id,:orig_code,:orig_name_id,:orig_izg_id,:orig_country_id,0,null, :barcode) into :ware_id;
4. ЗАЧЕМ??? Все карточки должны быть в wares_log!!!
- Если всетаки нашлась карточка, то берем из нее реальные поля:
if (ware_id is not null) then
begin
goodname=sname;
goodizg=sizg;
goodcountry=scountry;
goodbarcode=barcode;
suspend;
exit;
end
- Затем пытаемся отдельно привести каждое из реальных полей.
- Если есть оригинальное значение, то ищем первую попавшуюся карточку товара с данным значением:
select first 1 id from wares where orig_name_id=:orig_name_id order by id desc into :ware_id;
5. Зачем??? В таблице wares оригинальные поля вообще не будут актуальными!!!
- Если не нашли, то приводим значение через связки:
if (ware_id is null) then select first 1 iif(actual_ware_id is null, id, actual_ware_id) from wares_log where orig_name_id=:orig_name_id order by log_id desc into :ware_id;
6. Поле log_id имеет тип d$uuid - связка может найтись не самая актуальная.
- Если мы ничего не нашли, то ищем по реальному полю. Точно также: сначала в таблице wares, затем wares_log.
if ((ware_id is null) and (name_id is not null)) then
begin
select first 1 id from wares where name_id=:name_id into :ware_id;
if (ware_id is null) then
select first 1 iif(actual_ware_id is null, id, actual_ware_id) from wares_log where name_id=:name_id order by log_id desc into :ware_id;
end
7. Почему бы сразу не искать в таблице wares_log???
- Затем точно также делаем по изготовителю и стране.
- Возвращаем полученные значения.
Этап 2: Проведение активного документа
На каждый товар срабатывает процедура PR_GET_WARE.
- Берутся и при необходимости создаются справочные значения для всех реальных и оригинальных полей:
select VAL_ID from PR_GETVAL_ID(:SNAME, 0, :ALTTYPE, :MNN) into :NAME_ID; ...
- Идет поиск карточки товара по реальным полям:
select ID from WARES where NAME_ID = :NAME_ID and IZG_ID = :IZG_ID and COUNTRY_ID = :COUNTRY_ID and BARCODE = :BARCODE into :W_ID;
- Если карточка нашлась, то выходим из процедуры, иначе создаем новую карточку:
if (W_ID is null) then
begin
W_ID = uuid_to_char(gen_uuid());
insert into WARES (ID, NAME_ID, IZG_ID, COUNTRY_ID, ORIG_CODE, ORIG_NAME_ID, ORIG_IZG_ID, ORIG_COUNTRY_ID, BARCODE, Z_ID, SKLAD_ID)
values (:W_ID, :NAME_ID, :IZG_ID, :COUNTRY_ID, :ORIG_CODE, :ORIG_NAME_ID, :ORIG_IZG_ID, :ORIG_COUNTRY_ID, :BARCODE, :Z_ID, :SKLAD_ID);
end
suspend;
Установка процедур
Устанавливаем процедуру PR_GET_WARE.
SET TERM ^ ;
create or alter procedure PR_INSTALL_PR_GET_WARE
as
declare variable IDX_U_EXISTS DM_STATUS;
declare variable IDX_100_EXISTS DM_STATUS;
declare variable GLOBAL_ID DM_STATUS;
declare variable INDEX_NAME DM_TEXT;
declare variable S DM_TEXT_BIG;
declare variable FIELD DM_TEXT;
begin
/* определяем база с глобальными наименованиями или нет */
if ((select upper(RF.RDB$FIELD_SOURCE)
from RDB$RELATION_FIELDS RF
where 1 = 1
and RF.RDB$FIELD_NAME = 'ID'
and RF.RDB$RELATION_NAME = 'WARES') = 'DM_UUID') then
GLOBAL_ID = 1;
else
GLOBAL_ID = 0;
/* определяем единое окно установлено или нет */
if ((select first 1 count(1)
from RDB$INDICES RIN
where RIN.RDB$INDEX_NAME = 'WARES_IDX_U'
and RIN.RDB$RELATION_NAME = 'WARES') > 0) then
IDX_U_EXISTS = 1;
else
IDX_U_EXISTS = 0;
/* определяем из какого индекса брать список полей, отвечающих за уникальность товаров */
if (IDX_U_EXISTS = 1) then
INDEX_NAME = 'WARES_IDX_U';
else
INDEX_NAME = 'WARES_IDX1';
/* определяем установлен ли хэш индекс */
if ((select first 1 count(1)
from RDB$INDICES RIN
where RIN.RDB$INDEX_NAME = 'WARES_IDX100'
and RIN.RDB$RELATION_NAME = 'WARES') > 0) then
IDX_100_EXISTS = 1;
else
IDX_100_EXISTS = 0;
/* входные параметры процедуры */
S = '
create or alter procedure PR_GET_WARE (
SNAME type of DM_TEXT,
SIZG type of DM_TEXT,
SCOUNTRY type of DM_TEXT,
ORIG_CODE type of DM_TEXT = '''',
SORIG_NAME type of DM_TEXT = '''',
SORIG_IZG type of DM_TEXT = '''',
SORIG_COUNTRY type of DM_TEXT = '''',
BARCODE type of DM_TEXT = '''',
Z_ID type of DM_ID = 0,
SKLAD_ID DM_TEXT = '''',
ALTTYPE DM_STATUS = 0,
MNN DM_TEXT = '''')
returns (
';
/* выходные параметры процедуры */
if (GLOBAL_ID = 1) then
S = S || 'W_ID type of DM_UUID_NULL)';
else
S = S || 'W_ID type of DM_ID)';
/* внутренние параметры процедуры */
S = S || ' as
declare variable OLD_BARCODE DM_TEXT1024;';
/* для базы с глобальными наименованиями типы полей DM_UUID_NULL */
if (GLOBAL_ID = 1) then
S = S || '
declare variable NAME_ID type of DM_UUID_NULL;
declare variable IZG_ID type of DM_UUID_NULL;
declare variable COUNTRY_ID type of DM_UUID_NULL;
declare variable ORIG_NAME_ID type of DM_UUID_NULL;
declare variable ORIG_IZG_ID type of DM_UUID_NULL;
declare variable ORIG_COUNTRY_ID type of DM_UUID_NULL;
declare variable WHASH DM_ID;
';
else
/* для базы без глобальных наименований типы полей DM_ID */
S = S || '
declare variable NAME_ID type of DM_ID;
declare variable IZG_ID type of DM_ID;
declare variable COUNTRY_ID type of DM_ID;
declare variable ORIG_NAME_ID type of DM_ID;
declare variable ORIG_IZG_ID type of DM_ID;
declare variable ORIG_COUNTRY_ID type of DM_ID;
declare variable WHASH DM_ID;
';
S = S || '
begin
';
/* вставляем в процедуру комментарии */
if (GLOBAL_ID = 1) then
S = S || ' /* BASE WITH GLOBAL ID */
';
else
S = S || ' /* BASE WITHOUT GLOBAL ID */
';
if (IDX_U_EXISTS = 1) then
S = S || ' /* BASE WITH WARES_IDX_U */
';
else
S = S || ' /* BASE WITHOUT WARES_IDX_U */
';
if (IDX_100_EXISTS = 1) then
S = S || ' /* BASE WITH WARES_IDX100 */
';
else
S = S || ' /* BASE WITHOUT WARES_IDX100 */
';
/* находим валсы для всех справочных значений */
S = S || ' if (ORIG_CODE is null) then
ORIG_CODE = '''';
select VAL_ID
from PR_GETVAL_ID(:SNAME, 0, :ALTTYPE, :MNN)
into :NAME_ID;
select VAL_ID
from PR_GETVAL_ID(:SIZG, 3, :ALTTYPE)
into :IZG_ID;
select VAL_ID
from PR_GETVAL_ID(:SCOUNTRY, 2, :ALTTYPE)
into :COUNTRY_ID;
select VAL_ID
from PR_GETVAL_ID(:SORIG_NAME, 1, :ALTTYPE)
into :ORIG_NAME_ID;
select VAL_ID
from PR_GETVAL_ID(:SORIG_IZG, 6, :ALTTYPE)
into :ORIG_IZG_ID;
select VAL_ID
from PR_GETVAL_ID(:SORIG_COUNTRY, 5, :ALTTYPE)
into :ORIG_COUNTRY_ID;
';
/* если хэш индекса нет */
if (IDX_100_EXISTS = 0) then
begin
S = S || '
select ID,
BARCODE
from WARES
where 1 = 1
';
/* ищем варес по всем поляем, которые есть в индексе, отвечающем за уникальность карточек */
select list('and ' || trim(RIS.RDB$FIELD_NAME) || ' = :' || trim(RIS.RDB$FIELD_NAME), ascii_char(13))
from RDB$INDEX_SEGMENTS RIS
where RIS.RDB$INDEX_NAME = :INDEX_NAME
into :FIELD;
S = S || :FIELD || '
into :W_ID,
:OLD_BARCODE;
';
end
else
/* если хэш индекс есть в базе */
begin
S = S || '
whash = (';
/* генерируем хэш по поляем в индексе */
select list('coalesce(:' || trim(RIS.RDB$FIELD_NAME) || ',''' || trim(RIS.RDB$FIELD_NAME) || ''')', ',')
from RDB$INDEX_SEGMENTS RIS
where RIS.RDB$INDEX_NAME = :INDEX_NAME
into :FIELD;
S = S || :FIELD || ');';
/* ищем варес по хэшу */
S = S || '
select ID,
BARCODE
from WARES
WHERE WHASH = :WHASH
into :W_ID,
:OLD_BARCODE;
';
end
/* если варес не нашли */
S = S || '
if (W_ID is null) then
begin
';
/* генерируем id */
if (GLOBAL_ID = 1) then
S = S || ' W_ID = uuid_to_char(gen_uuid());
';
else
S = S || ' W_ID = gen_id(GEN_WARES_ID, 1);
';
/* создаем новый варес */
S = S || ' insert into WARES (ID, NAME_ID, IZG_ID, COUNTRY_ID, ORIG_CODE, ORIG_NAME_ID, ORIG_IZG_ID, ORIG_COUNTRY_ID,
BARCODE, Z_ID, SKLAD_ID)
values (:W_ID, :NAME_ID, :IZG_ID, :COUNTRY_ID, :ORIG_CODE, :ORIG_NAME_ID, :ORIG_IZG_ID, :ORIG_COUNTRY_ID, :BARCODE,
:Z_ID, :SKLAD_ID);
end
else
';
/* если штрихкод не в индексе */
S = S || '
if (OLD_BARCODE <> BARCODE) then
update WARES
set BARCODE = :BARCODE
where ID = :W_ID;
';
S = S || '
suspend;
end
';
execute statement(S);
end^
SET TERM ; ^
/* Existing privileges on this procedure */
GRANT EXECUTE ON PROCEDURE PR_INSTALL_PR_GET_WARE TO SYSDBA;
EXECUTE PROCEDURE PR_INSTALL_PR_GET_WARE;
DROP PROCEDURE PR_INSTALL_PR_GET_WARE;