Подготовка серверной базы и скриптов для Единого Окна
Материал из wiki.standart-n.ru
Версия от 15:01, 6 сентября 2016; Aleksnick (обсуждение | вклад)
- Экспорт vals_link (для ЙО: boss:d:\обмен\JO\ZTRADE.FDB) как dbf или insert
- Создаем и вставляем данные vals_link в нашу БД (скрипт создания и импорта из dbf: cowa_vals_links.sql)
/******************************************************************************/
/*** Following SET SQL DIALECT is just for the Database Comparer ***/
/******************************************************************************/
SET SQL DIALECT 3;
/******************************************************************************/
/*** Tables ***/
/******************************************************************************/
CREATE GENERATOR GEN_VALS_LINKS_ID;
CREATE TABLE VALS_LINKS (
ID DM_ID NOT NULL,
RIGHT_VAL_ID DM_UUID,
WRONG_VAL_ID DM_UUID,
INSERTDT DM_DATETIME,
VTYPE DM_STATUS NOT NULL,
SRIGHT_VAL DM_TEXT,
SWRONG_VAL DM_TEXT,
DELETEDT DM_DATETIME
);
/******************************************************************************/
/*** Unique Constraints ***/
/******************************************************************************/
ALTER TABLE VALS_LINKS ADD CONSTRAINT UNQ1_VALS_LINKS UNIQUE (RIGHT_VAL_ID, WRONG_VAL_ID);
/******************************************************************************/
/*** Primary Keys ***/
/******************************************************************************/
ALTER TABLE VALS_LINKS ADD CONSTRAINT PK_VALS_LINKS PRIMARY KEY (ID);
/******************************************************************************/
/*** Indices ***/
/******************************************************************************/
CREATE INDEX VALS_LINKS_IDX1 ON VALS_LINKS (RIGHT_VAL_ID);
CREATE INDEX VALS_LINKS_IDX2 ON VALS_LINKS (WRONG_VAL_ID);
CREATE INDEX VALS_LINKS_IDX3 ON VALS_LINKS (SRIGHT_VAL, SWRONG_VAL);
CREATE INDEX VALS_LINKS_IDX4 ON VALS_LINKS (SRIGHT_VAL);
CREATE INDEX VALS_LINKS_IDX5 ON VALS_LINKS (SWRONG_VAL);
/******************************************************************************/
/*** Triggers ***/
/******************************************************************************/
SET TERM ^ ;
/******************************************************************************/
/*** Triggers for tables ***/
/******************************************************************************/
/* Trigger: VALS_LINKS_BI */
CREATE OR ALTER TRIGGER VALS_LINKS_BI FOR VALS_LINKS
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.id is null) then
new.id = gen_id(gen_vals_links_id,1);
new.insertdt=current_timestamp;
end
^
SET TERM ; ^
/******************************************************************************/
/*** Privileges ***/
/******************************************************************************/
execute ibeblock
as
begin
cbb = 'execute ibeblock (RecCount variant)
as
begin
if (ibec_Mod(RecCount, 100) = 0) then
ibec_Progress(RecCount || '' records imported.'');
end;';
DB = ibec_CreateConnection(__ctFirebird, 'DBName="standart-n:D:\STANDART-N\base_g\test\test_ztrade_g.fdb";
ClientLib=gds32.dll;
User=SYSDBA; Password=masterkey; Names=WIN1251; SqlDialect=3;');
try
ibec_UseConnection(DB);
Res = ibec_ImportData(DB, 'VALS_LINKS', __impDBase, 'D:\STANDART-N\base_g\test\SQLs\vals_links.dbf', '',
'RowFirst=1; RowLast=2147483647;
DateOrder=DMY; DateSeparator="."; TimeSeparator=":";', '', cbb);
if (Res is not null) then
ibec_ShowMessage(Res || ' records were imported successfully.');
finally
ibec_CloseConnection(DB);
end;
end
- Выпоняем cowa_all.sql (не оптимизирован для ЙО)
--копируем VALS_LINKS как объект
ALTER TRIGGER WARES_LOG_BI_DISTR INACTIVE;
ALTER TRIGGER WARES_LOG_BU_DISTR INACTIVE;
ALTER TRIGGER WARES_LOG_AD_DISTR INACTIVE;
ALTER TRIGGER WARES_AD_DISTR INACTIVE;
ALTER TRIGGER WARES_AU0 INACTIVE;
ALTER TRIGGER WARES_AIU0 INACTIVE;
ALTER TRIGGER VALS_AIU0 INACTIVE;
ALTER TRIGGER PARTS_AU0 INACTIVE;
ALTER TRIGGER VALS_AD_DISTR INACTIVE;
--ALTER TRIGGER VALS_AD_DODOUBLES INACTIVE;
--ALTER TRIGGER WARES_BIU_VALCHECK INACTIVE;
--ALTER TRIGGER WARES_AD_DISTR INACTIVE;
--ALTER TRIGGER WARES_AD0 INACTIVE;
ALTER TRIGGER WARES_BD0 INACTIVE;
ALTER TRIGGER WARES_BU_DISTR INACTIVE;
--ALTER TRIGGER WARES_BU0_MGN_NAME_ASNA INACTIVE;
--DROP INDEX WARES_IDX15;
--CREATE INDEX WARES_IDX15 ON WARES (NAME_ID,IZG_ID,COUNTRY_ID,ORIG_CODE,ORIG_NAME_ID,ORIG_IZG_ID,ORIG_COUNTRY_ID);
ALTER TABLE WARES_LOG
ADD ACTUAL_WARE_ID DM_UUID_NULL;
CREATE INDEX WARES_LOG_ACTUAL_WARE_ID ON WARES_LOG (ACTUAL_WARE_ID);
SET TERM ^ ;
CREATE OR ALTER trigger wares_log_bi_tmp for wares_log
active before insert position 0
AS
begin
if (new.log_id is null) then
new.log_id=UUID_TO_CHAR(GEN_UUID());
new.d$uuid=new.log_id;
if (new.d$srvupddt is null) then
begin
new.d$srvupddt='2000-01-01';
end
if (new.l_id is null) then
new.l_id=GEN_ID(GEN_WARES_LOG_ID,1);
new.log_insertdt=current_timestamp;
end^
SET TERM ; ^
SET TERM ^ ;
CREATE OR ALTER procedure PR_TMP_CHANGEWARES_CONSTR
as
declare variable UUID type of DM_UUID;
declare variable NAME_ID type of DM_UUID;
declare variable IZG_ID type of DM_UUID;
declare variable COUNTRY_ID type of DM_UUID;
declare variable BARCODE type of DM_TEXT;
declare variable ACTUAL_UUID type of DM_UUID;
begin
delete from wares_log wl where (ACTUAL_WARE_ID is null) and (not exists (select id from wares w where w.id=wl.id));
for
select min(d$uuid), name_id, izg_id, country_id, barcode from wares group by name_id, izg_id, country_id, barcode having count(1)>1
into actual_uuid, name_id, izg_id, country_id, barcode
do
begin
for select d$uuid from wares where name_id=:name_id and izg_id=:izg_id and country_id=:country_id and barcode=:barcode and d$uuid<>:actual_uuid into uuid
do begin
-- insert into tmp_todelete (TABLENAME,UUID,REASON,ACTUAL_UUID) values ('WARES',:uuid,'удаление',:actual_uuid);
insert into wares_log (ID,NAME_ID,IZG_ID,COUNTRY_ID,ORIG_CODE,ORIG_NAME_ID,ORIG_IZG_ID,ORIG_COUNTRY_ID,BARCODE,Z_ID,SKLAD_ID,INSERTDT,PACKET,L_ID,ACTUAL_WARE_ID)
select ID,NAME_ID,IZG_ID,COUNTRY_ID,ORIG_CODE,ORIG_NAME_ID,ORIG_IZG_ID,ORIG_COUNTRY_ID,BARCODE,Z_ID,SKLAD_ID,INSERTDT,PACKET,L_ID,:actual_uuid
from wares where d$uuid=:uuid;
update parts set ware_id=:actual_uuid where ware_id=:uuid;
delete from wares where d$uuid=:uuid;
end
end
--delete from wares w where not exists (select id from parts p where p.ware_id=w.id) = всего 11414 , после сжатия - игнорим пока
delete from vals v where (vtype=0) and (not exists (select id from wares w where w.name_id=v.id)) and (not exists (select id from wares_log wl where wl.name_id=v.id));
delete from vals v where (vtype=3) and (not exists (select id from wares w where w.izg_id=v.id)) and (not exists (select id from wares_log wl where wl.izg_id=v.id));
delete from vals v where (vtype=2) and (not exists (select id from wares w where w.country_id=v.id)) and (not exists (select id from wares_log wl where wl.country_id=v.id));
delete from vals v where (vtype=1) and (not exists (select id from wares w where w.orig_name_id=v.id)) and (not exists (select id from wares_log wl where wl.orig_name_id=v.id));
delete from vals v where (vtype=6) and (not exists (select id from wares w where w.orig_izg_id=v.id)) and (not exists (select id from wares_log wl where wl.orig_izg_id=v.id));
delete from vals v where (vtype=5) and (not exists (select id from wares w where w.orig_country_id=v.id)) and (not exists (select id from wares_log wl where wl.orig_country_id=v.id));
end^
SET TERM ; ^
update wares set barcode='' where barcode is null;
execute procedure PR_TMP_CHANGEWARES_CONSTR;
commit work;
CREATE UNIQUE INDEX WARES_IDX_U ON WARES (NAME_ID, IZG_ID, COUNTRY_ID, BARCODE);
--DROP TRIGGER WARES_LOG_BI_TMP;
CREATE TABLE TMP_UPDATED_WARES (
UUID DM_UUID /* DM_UUID = CHAR(36) NOT NULL */
);
CREATE INDEX TMP_UPDATED_WARES_IDX1 ON TMP_UPDATED_WARES (UUID);
/*
CREATE GENERATOR GEN_VALS_CARANTINE_ID;
CREATE TABLE VALS_CARANTINE (
ID DM_ID NOT NULL,
CUR_ID DM_UUID,
NEW_ID DM_UUID,
INSERTDT DM_DATETIME,
FROM_PROFILE_ID DM_ID_NULL
);
SET TERM ^ ;
CREATE OR ALTER TRIGGER VALS_CARANTINE_BI FOR VALS_CARANTINE
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.id is null) then
new.id = gen_id(gen_vals_carantine_id,1);
new.insertdt=current_timestamp;
if (new.from_profile_id is null) then
select from_profile_id from g$distribute where uuid=new.new_id into new.from_profile_id;
end
^
SET TERM ; ^
*/
SET TERM ^ ;
CREATE OR ALTER trigger vals_biu_dodoubles for vals
inactive before insert or update position 0
AS
declare variable ID type of DM_UUID;
begin
select id from vals where VTYPE=new.VTYPE and svalue=new.svalue and ALTTYPE=new.ALTTYPE and d$uuid<>new.d$uuid into :id;
if (id is null) then exit;
/*
0 - приведенное наименование
3 - приведенный производитель
2 - приведенная страна
1 - ориг. наименование
6 - ориг. производитель
5 - ориг. страна
Запускает цепочку апдейтов. При изменении wares проверяются дубли, и, в случае нахождения, правятся партии
*/
if (new.vtype=0) then
update wares set name_id=new.id where name_id=:id;
else if (new.vtype=3) then
update wares set izg_id=new.id where izg_id=:id;
else if (new.vtype=2) then
update wares set country_id=new.id where country_id=:id;
else if (new.vtype=1) then
update wares set orig_name_id=new.id where orig_name_id=:id;
else if (new.vtype=6) then
update wares set orig_izg_id=new.id where orig_izg_id=:id;
else if (new.vtype=5) then
update wares set orig_country_id=new.id where orig_country_id=:id;
else exit;
insert into vals_carantine (cur_id, new_id) values (:id, new.id);
delete from vals where id=:id;
end^
SET TERM ; ^
SET TERM ^ ;
CREATE OR ALTER trigger wares_biu_cowa for wares
active before insert or update position 0
AS
declare variable cur_id type of DM_UUID;
begin
cur_id=null;
select d$uuid from wares where
NAME_ID=new.name_id and IZG_ID=new.izg_id and COUNTRY_ID=new.COUNTRY_ID and BARCODE=new.BARCODE and d$uuid<>new.d$uuid into :cur_id;
if (cur_id is null) then exit;
if (not exists(select id from wares_log where id=:cur_id and actual_ware_id=new.id)) then
begin
update wares_log set ACTUAL_WARE_ID=new.d$uuid where ACTUAL_WARE_ID=:cur_id;
insert into wares_log (ID,NAME_ID,IZG_ID,COUNTRY_ID,ORIG_CODE,ORIG_NAME_ID,ORIG_IZG_ID,ORIG_COUNTRY_ID,BARCODE,Z_ID,SKLAD_ID,INSERTDT,PACKET,L_ID,ACTUAL_WARE_ID)
select ID,NAME_ID,IZG_ID,COUNTRY_ID,ORIG_CODE,ORIG_NAME_ID,ORIG_IZG_ID,ORIG_COUNTRY_ID,BARCODE,Z_ID,SKLAD_ID,INSERTDT,PACKET,L_ID,new.d$uuid from wares where d$uuid=:cur_id;
-- values (new.ID,new.NAME_ID,new.IZG_ID,new.COUNTRY_ID,new.ORIG_CODE,new.ORIG_NAME_ID,new.ORIG_IZG_ID,new.ORIG_COUNTRY_ID,new.BARCODE,new.Z_ID,new.SKLAD_ID,new.INSERTDT,new.PACKET,new.L_ID,new.d$uuid);
end
update parts set ware_id=new.d$uuid where ware_id=:cur_id;
delete from wares where d$uuid=:cur_id;
end^
SET TERM ; ^
SET TERM ^ ;
CREATE OR ALTER trigger parts_biu_cowa for parts
active before insert or update position 0
AS
declare variable ware_id type of DM_UUID;
begin
if (exists(select id from wares where id=new.ware_id)) then exit;
select max(actual_ware_id) from wares_log where id=new.ware_id and (exists(select id from wares w where w.d$uuid=actual_ware_id)) into :ware_id;
if (ware_id is null) then exit;
-- if (exists(select id from wares where d$uuid=:ware_id)) then
new.ware_id=:ware_id;
end^
SET TERM ; ^
SET TERM ^ ;
CREATE OR ALTER procedure UTPR_REMOVE_TILDA (
SVALUE type of DM_TEXT)
returns (
S type of DM_TEXT)
as
declare variable TILDA type of DM_TEXT;
declare variable C char(10);
begin
s=:svalue;
if (svalue not starting with '~') then
begin
suspend;
exit;
end
tilda='';
if (svalue starting with '~100') then
begin
s=substring(svalue from 5 for 245);
tilda='100';
end
else
begin
c=substring(svalue from 3 for 1);
if (c in ('0','1','2','3','4','5','6','7','8','9')) then
begin
s=substring(svalue from 4 for 245);
tilda=substring(svalue from 2 for 2);
end
else
begin
s=substring(svalue from 3 for 245);
tilda=substring(svalue from 2 for 1);
end
c=substring(s from 1 for 1);
if (c='@') then
begin
s=substring(s from 2);
end
end
suspend;
end^
SET TERM ; ^
SET TERM ^ ;
CREATE OR ALTER procedure UTPR_BUBBLE_SORT (
SOURCE DM_TEXT)
returns (
S DM_TEXT)
as
declare variable C1 char(1);
declare variable L integer;
declare variable I integer;
declare variable SWAPPED integer;
declare variable J integer;
declare variable C2 char(1);
declare variable B char(1);
begin
l=char_length(source);
i=0;
s=source;
while (i<=l) do
begin
i=i+1; j=0;
swapped=0;
while (j<=l-i-1) do
begin
j=j+1;
c1=substring(s from j for 1);
c2=substring(s from j+1 for 1);
if (c1>c2) then
begin
b=c1;
s=substring(s from 1 for j - 1) || c2 || c1 || substring(s from j + 2);
swapped=1;
end
end
if (swapped=0) then break;
end
suspend;
end^
SET TERM ; ^
SET TERM ^ ;
CREATE OR ALTER procedure UTPR_CHARSONLY (
SOURCE type of DM_TEXT,
SORTED integer = 0)
returns (
S DM_TEXT)
as
declare variable C char(1);
declare variable L integer;
declare variable I integer;
declare variable V integer;
begin
l=char_length(source);
i=1;
s='';
while (i<=l) do
begin
c=substring(source from i for 1);
v=ascii_val(c);
if (((v>47) and (v<58)) or
((v>64) and (v<91)) or
((v>96) and (v<123)) or
(v>191)) then
s=s||c;
i=i+1;
end
if (sorted=1) then
select s from UTPR_BUBBLE_SORT(:s) into :s;
suspend;
end^
SET TERM ; ^
SET TERM ^ ;
CREATE OR ALTER procedure PR_TMP_COMPRESS_VALS
as
declare variable UVALUE type of DM_TEXT;
declare variable VTYPE type of DM_STATUS;
declare variable ID type of DM_UUID;
declare variable W_CNT type of DM_STATUS;
declare variable T_CNT type of DM_STATUS;
declare variable T_ID type of DM_UUID;
begin
-- update vals set uppervalue=upper(trim((select s from UTPR_REMOVE_TILDA(svalue)))), isactual=0;
update vals set uppervalue=(select s from UTPR_CHARSONLY(upper(trim((select s from UTPR_REMOVE_TILDA(svalue)))),1)), isactual=0;
-- for select uppervalue, vtype from vals where vtype in (0,3,2) and svalue<>'' group by vtype, uppervalue having count(1)>1 into uvalue, vtype do
for select uppervalue, vtype from vals where vtype in (0,3,2) group by vtype, uppervalue having count(1)>1 into uvalue, vtype do
begin
T_CNT=0; t_id=null;
for select id from vals where vtype=:vtype and uppervalue=:uvalue into id do
begin
if (vtype=0) then
select count(1) from wares where name_id=:id into :w_cnt;
else if (vtype=3) then
select count(1) from wares where izg_id=:id into :w_cnt;
else if (vtype=2) then
select count(1) from wares where country_id=:id into :w_cnt;
if (t_cnt<w_cnt) then
begin
t_cnt=w_cnt;
t_id=:id;
end
update vals set isactual=:w_cnt where id=:id;
end
if (t_id is not null) then
begin
for select id from vals where vtype=:vtype and uppervalue=:uvalue and id<>:t_id into id do
begin
if (vtype=0) then
begin
insert into TMP_UPDATED_WARES (uuid) select d$uuid from wares where name_id=:id;
update wares set name_id=:t_id where name_id=:id;
end
else if (vtype=3) then
begin
insert into TMP_UPDATED_WARES (uuid) select d$uuid from wares where izg_id=:id;
update wares set izg_id=:t_id where izg_id=:id;
end
else if (vtype=2) then
begin
insert into TMP_UPDATED_WARES (uuid) select d$uuid from wares where country_id=:id;
update wares set country_id=:t_id where country_id=:id;
end
end
end
end
end^
SET TERM ; ^
CREATE INDEX VALS_IDX_COWA_TMP ON VALS (VTYPE, UPPERVALUE);
execute procedure PR_TMP_COMPRESS_VALS;
commit work;
SET TERM ^ ;
CREATE OR ALTER procedure PR_TMP_APPLY_VALS_LINKS
as
declare variable RIGHT_ID type of DM_UUID;
declare variable WRONG_ID type of DM_UUID;
begin
for select vl.right_val_id, vl.wrong_val_id from vals_links vl where vtype=0 into right_id, wrong_id do
begin
insert into TMP_UPDATED_WARES (uuid) select d$uuid from wares where name_id=:wrong_id;
update wares set name_id=:right_id where name_id=:wrong_id;
end
for select vl.right_val_id, vl.wrong_val_id from vals_links vl where vtype=3 into right_id, wrong_id do
begin
insert into TMP_UPDATED_WARES (uuid) select d$uuid from wares where izg_id=:wrong_id;
update wares set izg_id=:right_id where izg_id=:wrong_id;
end
for select vl.right_val_id, vl.wrong_val_id from vals_links vl where vtype=2 into right_id, wrong_id do
begin
insert into TMP_UPDATED_WARES (uuid) select d$uuid from wares where country_id=:wrong_id;
update wares set country_id=:right_id where country_id=:wrong_id;
end
end^
SET TERM ; ^
execute procedure PR_TMP_APPLY_VALS_LINKS;
commit work;
DROP TRIGGER WARES_LOG_BI_TMP;
ALTER TRIGGER WARES_AU0 INACTIVE;
ALTER TRIGGER WARES_AIU0 INACTIVE;
ALTER TRIGGER VALS_AIU0 INACTIVE;
ALTER TRIGGER WARES_LOG_BI_DISTR ACTIVE;
ALTER TRIGGER WARES_LOG_BU_DISTR ACTIVE;
ALTER TRIGGER WARES_LOG_AD_DISTR ACTIVE;
ALTER TRIGGER WARES_AD_DISTR ACTIVE;
ALTER TRIGGER PARTS_AU0 ACTIVE;
- Для связывания по ШК выполняем cowa_bcode_links.sql (не оптимизирован для ЙО)
- Проверяем работу, смотрим сколько записей добавилось в g$distribute - могут добавится немного записей и только по таблицам wares и wares_log.
- Экспорт как insert скрипт в файл запроса "select * from wares_log wl where wl.actual_ware_id is not null", все строки "commit work" - убираем.
- Экспрорт как update or insert скрипт в файл запроса "select distinct w.* from TMP_UPDATED_WARES t left join wares w on t.uuid=w.d$uuid where w.d$uuid is not null", все строки "commit work" - убираем.
- Делаем шаблоны G$TASKS_TMPL по образцу. Заменить data в записях cowa_02XX на файл, созданный в 6м пункте, cowa_08 - на файл 7го пункта.