====== Восстановление работы конвейера, после воссоздания БД.docx ====== Восстановление работы конвейеров после пересоздания базы данных (из БД основного сервера). Так как таблицы конвейера CONVEYORS и CONVEYOR_LOAD не репликационные, то после пересоздания БД из базы основного сервера, таблицы конвейеров будут таблицами из БД основного сервера. Чтобы восстановить работоспособность конвейера, необходимо в программе IBExpert, на старой базе сделать экспорт таблиц CONVEYORS и CONVEYOR_LOAD в скрипт, выбрав в настройке Export as – INSERT Statements. Сохранить скрипт (см. рис. 1). {{:Vosstanovleniye_raboty_konveyyera_posle_vossozdaniya_BD_docx_2022-02-21_14-18-34_img1.png?623x313}} Рис. 1 В новой БД, обнулить таблицу CONVEYOR_LOAD, если там есть записи. В IBExpert выбрать Tools -> SQL Editor (F12), выполнить команду delete from CONVEYER_LOAD, выполнить Commit Transaction. Запустить из меню Tools -> Script Executive (Ctrl+F12), открыть скрипт для таблицы CONVEYORS (1) и выбрав новую БД (2) и Use current connection (3), запустить скрипт на выполнение. Удалить из Таблицы CONVEYORS, запись для конвейера из основной БД. Аналогично запустить скрипт для изменения таблицы CONVEYOR_LOAD (см. рис. 2) {{:Vosstanovleniye_raboty_konveyyera_posle_vossozdaniya_BD_docx_2022-02-21_14-18-34_img2.png?697x390}} Рис. 2 Перезагрузить Агента. Если конвейер работает с использованием сенсорного поста, по старой схеме (сенсорный пост общается с БД напрямую, в логах Агента, отсутствует лог ConvAgent) , нужно убедится, что в новой БД есть процедуры CONVEYOR_CHECKORDER , CONVEYOR_FINDEMPTYCELLS, CONVEYOR_FINDEORDERCELLS и CONVEYOR_SAVELOADORDER (см. рис. 2). Если их нет, необходимо скопировать текс процедуры: SET TERM ^ ; create or alter procedure CONVEYOR_CHECKORDER ( ORDER_BARCODE varchar(25)) returns ( RESULT integer, ID bigint, NUM varchar(50)) as declare variable STATUS integer; begin select count(c.id), o.id, d.doc_num, o.status_id from conveyor_load c right join docs_order o on c.order_id = o.id inner join docs d on d.doc_id= o.doc_id where o.barcode = :ORDER_BARCODE group by o.id, d.doc_num, o.status_id into :RESULT, :ID, :NUM, STATUS; if (RESULT is null) then RESULT = -1; else if (STATUS>4) then RESULT = -2; suspend; end^ SET TERM ; ^ COMMENT ON PARAMETER CONVEYOR_CHECKORDER.RESULT IS '-1 - заказ не существует, -2 - заказ закрыт, 0 - заказ не на конвейере, >0 - заказ на конвейере'; COMMENT ON PARAMETER CONVEYOR_CHECKORDER.ID IS 'id заказа (null если не существует)'; COMMENT ON PARAMETER CONVEYOR_CHECKORDER.NUM IS 'номер заказа'; COMMENT ON PARAMETER CONVEYOR_CHECKORDER.ORDER_BARCODE IS 'штрихкод заказа'; /* Following GRANT statetements are generated automatically */ GRANT SELECT ON CONVEYOR_LOAD TO PROCEDURE CONVEYOR_CHECKORDER; GRANT SELECT ON DOCS_ORDER TO PROCEDURE CONVEYOR_CHECKORDER; GRANT SELECT ON DOCS TO PROCEDURE CONVEYOR_CHECKORDER; /* Existing privileges on this procedure */ GRANT EXECUTE ON PROCEDURE CONVEYOR_CHECKORDER TO SYSDBA; SET TERM ^ ; create or alter procedure CONVEYOR_FINDEMPTYCELLS ( CONVEYOR_ID integer not null, NEED_CELLS integer not null) returns ( TARGET_CELL integer, BEGIN_CELL integer, END_CELL integer) as declare variable MIN_CELL integer; /* номер начальной ячейки конвейера */ declare variable MAX_CELL integer; /* номер последней ячейки конвейера */ declare variable PREV_CELL integer; declare variable CUR_CELL integer; begin TARGET_CELL = -1; select c.cell_num_start, c.cell_num_end from conveyors c where c.id = :CONVEYOR_ID into :MIN_CELL, :MAX_CELL; PREV_CELL = MIN_CELL-1; for select c.cell_num from conveyor_load c where (c.conveyor_id = :CONVEYOR_ID)and(c.dos_id is not null or c.order_id is not null) order by c.cell_num into :CUR_CELL do begin if (CUR_CELL-PREV_CELL > NEED_CELLS) then begin TARGET_CELL = PREV_CELL+trunc(NEED_CELLS/2)+1; BEGIN_CELL = PREV_CELL+1; END_CELL = PREV_CELL+NEED_CELLS; end else PREV_CELL = CUR_CELL; end if ((TARGET_CELL = -1)and(MAX_CELL+1-PREV_CELL > NEED_CELLS)) then begin TARGET_CELL = PREV_CELL+trunc(NEED_CELLS/2)+1; BEGIN_CELL = PREV_CELL+1; END_CELL = PREV_CELL+NEED_CELLS; end suspend; end^ SET TERM ; ^ COMMENT ON PARAMETER CONVEYOR_FINDEMPTYCELLS.TARGET_CELL IS 'номер ячейки перехода (-1 - нет свободных ячеек)'; COMMENT ON PARAMETER CONVEYOR_FINDEMPTYCELLS.BEGIN_CELL IS 'начальная ячейка диапазона'; COMMENT ON PARAMETER CONVEYOR_FINDEMPTYCELLS.END_CELL IS 'конечная ячейка диапазона'; COMMENT ON PARAMETER CONVEYOR_FINDEMPTYCELLS.CONVEYOR_ID IS 'id конвейера'; COMMENT ON PARAMETER CONVEYOR_FINDEMPTYCELLS.NEED_CELLS IS 'запрашиваемый диапазон пустых ячеек'; /* Following GRANT statetements are generated automatically */ GRANT SELECT ON CONVEYORS TO PROCEDURE CONVEYOR_FINDEMPTYCELLS; GRANT SELECT ON CONVEYOR_LOAD TO PROCEDURE CONVEYOR_FINDEMPTYCELLS; /* Existing privileges on this procedure */ GRANT EXECUTE ON PROCEDURE CONVEYOR_FINDEMPTYCELLS TO SYSDBA; SET TERM ^ ; create or alter procedure CONVEYOR_FINDORDERCELLS ( CONVEYOR_ID integer not null, DOR_ID bigint not null) returns ( TARGET_CELL integer, BEGIN_CELL integer, END_CELL integer) as declare variable TMP_CELL integer; declare variable CUR_CELL integer; begin BEGIN_CELL = -1; END_CELL = -1; for select c.cell_num from conveyor_load c where (c.conveyor_id = :CONVEYOR_ID)and(c.order_id = :DOR_ID) order by c.cell_num into :CUR_CELL do begin if (CUR_CELL-1 = END_CELL) then begin END_CELL = CUR_CELL; end else begin if (BEGIN_CELL > 0) then begin TARGET_CELL = BEGIN_CELL+trunc((END_CELL-BEGIN_CELL)/2); suspend; end BEGIN_CELL = CUR_CELL; END_CELL = CUR_CELL; end end if (BEGIN_CELL > 0) then begin TARGET_CELL = BEGIN_CELL+trunc((END_CELL-BEGIN_CELL)/2); suspend; end end^ SET TERM ; ^ COMMENT ON PARAMETER CONVEYOR_FINDORDERCELLS.TARGET_CELL IS 'номер ячейки перехода (-1 - нет ячеек с данным заказом)'; COMMENT ON PARAMETER CONVEYOR_FINDORDERCELLS.BEGIN_CELL IS 'начальная ячейка диапазона'; COMMENT ON PARAMETER CONVEYOR_FINDORDERCELLS.END_CELL IS 'конечная ячейка диапазона'; COMMENT ON PARAMETER CONVEYOR_FINDORDERCELLS.CONVEYOR_ID IS 'id конвейера'; COMMENT ON PARAMETER CONVEYOR_FINDORDERCELLS.DOR_ID IS 'id заказа'; /* Following GRANT statetements are generated automatically */ GRANT SELECT ON CONVEYOR_LOAD TO PROCEDURE CONVEYOR_FINDORDERCELLS; /* Existing privileges on this procedure */ GRANT EXECUTE ON PROCEDURE CONVEYOR_FINDORDERCELLS TO SYSDBA; SET TERM ^ ; create or alter procedure CONVEYOR_SAVELOADORDER ( CONV_ID bigint, BEGIN_CELL integer, END_CELL integer, DOR_ID integer) returns ( RESULT integer) as declare variable CELL_NUM integer; begin CELL_NUM = BEGIN_CELL; while (CELL_NUM <= END_CELL) do begin update or insert into conveyor_load (conveyor_id, cell_num, order_id) values (:CONV_ID, :CELL_NUM, :DOR_ID) matching (cell_num); CELL_NUM = CELL_NUM +1; end RESULT = 0; suspend; end^ SET TERM ; ^ COMMENT ON PARAMETER CONVEYOR_SAVELOADORDER.CONV_ID IS 'id конвейера'; COMMENT ON PARAMETER CONVEYOR_SAVELOADORDER.BEGIN_CELL IS 'начальная ячейка диапазона'; COMMENT ON PARAMETER CONVEYOR_SAVELOADORDER.END_CELL IS 'конечная ячейка диапазона'; COMMENT ON PARAMETER CONVEYOR_SAVELOADORDER.DOR_ID IS 'id заказа'; /* Following GRANT statetements are generated automatically */ GRANT SELECT,INSERT,UPDATE ON CONVEYOR_LOAD TO PROCEDURE CONVEYOR_SAVELOADORDER; /* Existing privileges on this procedure */ GRANT EXECUTE ON PROCEDURE CONVEYOR_SAVELOADORDER TO SYSDBA; Запустить Script Executive, вставить в окно текст процедуры и выбрав текущую базу и Use current connect, запустить скрипт на выполнение. Перезагрузить сенсорный пост и Агента.