Informix 中插入触发器的自引用更新

Posted

技术标签:

【中文标题】Informix 中插入触发器的自引用更新【英文标题】:Self reference update on insert trigger in Informix 【发布时间】:2011-12-05 10:28:24 【问题描述】:

我正在将各种来源的数据提取到一张表中。在这个新表中,有一个名为 lineno 的字段。该字段值应根据公司代码和批号依次排列。我写了以下程序

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 语句引起的错误作用于触发表,在这种情况下是 UPDATE 语句。 所以我的问题是,我该如何解决这个问题?有什么变通或更好的解决方案吗?

【问题讨论】:

【参考方案1】:

我认为需要重新考虑设计。首先,如果从 tmp_cb_rcpthdr 中删除某些行会发生什么? COUNT(*) 查询将导致重复的 lineno 值。

即使这只是一个 ETL 流程,并且您可以确信数据不会从其他地方被操纵,性能也会成为一个问题,而且您拥有的公司和任何一种组合的数据越多,性能只会变得更糟batch_id。

lineno 是否需要从零开始递增,还是只是为了保持原始加载顺序?因为如果是后者,表上的SEQUENCESERIAL 字段将达到相同的目的,并且效率更高很多

如果您必须以这种方式生成lineno,我建议您创建第二个控制表,以公司和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 documentation for more,了解如何将计算值与触发器结合使用。

【讨论】:

谢谢 RET。我已经应用了您的解决方案,并且效果很好。是的,这仅适用于仅由我手动运行的 ETL 过程。所以我不担心性能或数据完整性。

以上是关于Informix 中插入触发器的自引用更新的主要内容,如果未能解决你的问题,请参考以下文章

更新/插入/删除表中的行后触发的触发器有问题

在 informix 触发器中传递连接的字符串参数

如何在informix中创建触发器?

警告:使用编译错误创建触发器?

sql插入的操作

插入更新触发器如何确定是插入还是更新