Самостоятельное обновление ссылки на триггер вставки в Informix - PullRequest
2 голосов
/ 05 декабря 2011

Я извлекаю данные из разных источников в одну таблицу.В этой новой таблице есть поле, называемое бельем.Это значение поля должно быть в последовательности, основанной на балансовой единице и номере партии.Я написал следующую процедуру

CREATE PROCEDURE update_line(company CHAR(4), batch CHAR(8), rcptid CHAR(12));

DEFINE lineno INT;

SELECT Count(*) 
INTO lineno
FROM tmp_cb_rcpthdr
WHERE cbrh_company = company
AND cbrh_batchid = batch;

UPDATE tmp_cb_rcpthdr
SET cbrh_lineno = lineno + 1
WHERE cbrh_company = company
AND cbrh_batchid = batch
AND cbrh_rcptid = rcptid;

END PROCEDURE;

Эта процедура будет вызываться с использованием следующего триггера

CREATE TRIGGER tmp_cb_rcpthdr_ins INSERT ON tmp_cb_rcpthdr 
REFERENCING NEW AS n
FOR EACH ROW
(
    EXECUTE PROCEDURE update_line(n.company, cbrh_batchid, cbrh_rcptid)
);

Однако я получил следующую ошибку

Ошибка SQL = -747 Таблица или столбец соответствуют объекту, указанному в операторе триггера.

Из oninit.com я узнаю, что ошибка, вызванная триггерным оператором SQL, действует на триггерную таблицу, которая в данном случаеОБНОВЛЕНИЕ заявление.Итак, мой вопрос, как мне решить эту проблему?Есть ли решение вокруг или лучшее решение?

1 Ответ

1 голос
/ 06 декабря 2011

Я думаю, что дизайн должен быть пересмотрен. Для начала, что произойдет, если некоторые строки будут удалены из tmp_cb_rcpthdr? Запрос COUNT(*) приведет к дублированию значений lineno.

Даже если это процесс только для ETL, и вы можете быть уверены, что данными не будут манипулировать из других источников, производительность будет проблемой, и она будет только ухудшаться, чем больше данных у вас будет для любой комбинации компании и batch_id.

Нужно ли бельё увеличивать с нуля, или это просто для поддержания первоначального порядка загрузки? Потому что, если это последнее, поле SEQUENCE или SERIAL в таблице достигнет того же конца и будет лот более эффективным.

Если вы должны сгенерировать lineno таким образом, я бы посоветовал вам создать вторую контрольную таблицу с ключом company и batch_id, которая отслеживает текущее значение lineno, то есть: (не проверено)

CREATE PROCEDURE update_line(company CHAR(4), batch CHAR(8));

    DEFINE lineno INT;

    SELECT cbrh_lineno INTO lineno 
    FROM linenoctl
    WHERE cbrh_company = company
    AND cbrh_batchid = batch;

    UPDATE linenoctl
    SET cbrh_lineno = lineno + 1
    WHERE cbrh_company = company
    AND cbrh_batchid = batch;
    -- A test that no other process has grabbed this record
    -- might need to be considered here, ie cbrh_lineno = lineno

    RETURN lineno + 1
END PROCEDURE;

Затем используйте его следующим образом:

CREATE TRIGGER tmp_cb_rcpthdr_ins INSERT ON tmp_cb_rcpthdr 
REFERENCING NEW AS n
FOR EACH ROW
(
    EXECUTE PROCEDURE update_line(n.company, cbrh_batchid) INTO cbrh_lineno
);

См. Документацию IDS для получения дополнительной информации об использовании вычисленных значений с триггерами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...