triggers - 是否可以使用序列的 nextval 作为 infomrix 数据库中表中字段的默认值?
问题描述
我有一个名为 T1 的表,其中包含一个字段id(int8)
和一个名为seq_id
.
我可以在 informix 数据库中seq_id.nextval
用作默认值吗?id
或者另一种方式,我可以id
在插入之前使用触发器进行更新seq_id.nextval
吗?
解决方案
在 Informix 中,您不能将序列NEXTVAL
用作列的默认值。
一种选择是将列转换为BIGSERIAL
.
其他选项是使用插入触发器。我没有找到直接NEXTVAL
在触发器定义中分配序列的方法,但是可以通过使用存储过程来完成。
CREATE SEQUENCE seq_id
INCREMENT BY 1 START WITH 1
MINVALUE 0
NOCYCLE CACHE 10
ORDER;
CREATE TABLE t1
(
id BIGINT NOT NULL
, val1 CHAR(4)
);
我找到了两种使用该程序的方法。返回序列的通用过程和将序列分配给 idNEXTVAL
的触发过程。NEXTVAL
使用通用过程:
CREATE FUNCTION spl_get_seq_id()
RETURNING BIGINT AS seq_id_next;
DEFINE seq_id_next BIGINT;
LET seq_id_next = seq_id.NEXTVAL;
RETURN seq_id_next;
END FUNCTION;
CREATE TRIGGER t1_ti
INSERT ON t1 REFERENCING NEW AS new_ins
FOR EACH ROW
(
EXECUTE FUNCTION spl_get_seq_id() INTO id
);
向表中插入一些值并检查结果:
INSERT INTO t1( id, val1 ) VALUES ( 1000, 'AAAA' );
INSERT INTO t1( val1 ) VALUES ( 'AAAB' );
INSERT INTO t1( id ) VALUES ( 1 );
INSERT INTO t1( id, val1 ) VALUES ( NULL::BIGINT, 'AAAD' );
SELECT * FROM t1;
id val1
1 AAAA
2 AAAB
3
4 AAAD
使用触发程序:
DROP TRIGGER t1_ti;
CREATE PROCEDURE t1_ti_spl_get_seq_id()
REFERENCING NEW AS new_values FOR t1;
LET new_values.id = seq_id.NEXTVAL;
END PROCEDURE;
CREATE TRIGGER t1_ti
INSERT ON t1
FOR EACH ROW
(
EXECUTE PROCEDURE t1_ti_spl_get_seq_id() WITH TRIGGER REFERENCES
);
向表中插入一些值并检查结果:
INSERT INTO t1( id, val1 ) VALUES ( 1000, 'AAAE' );
INSERT INTO t1( val1 ) VALUES ( 'AAAF' );
INSERT INTO t1( id ) VALUES ( 1 );
INSERT INTO t1( id, val1 ) VALUES ( NULL::BIGINT, 'AAAH' );
SELECT * FROM t1;
id val1
1 AAAA
2 AAAB
3
4 AAAD
5 AAAE
6 AAAF
7
8 AAAH
我用于BIGINT
该id
列,但它应该适用INT8
(至于我为什么使用它,似乎有一些好处:计数器和代码:BIGINT、INT8、INTEGER 和 SMALLINT)。
编辑1:
作为对您的评论的回应,您可以根据会话用户尝试触发器上的条件。这仅在 cdc 软件使用专用用户时才有效。在此示例中,cdc_agent
是 cdc 软件在 Informix 中使用的用户。
DATABASE db1;
GRANT CONNECT TO cdc_agent;
GRANT CONNECT TO myuser;
CREATE SEQUENCE seq_id
INCREMENT BY 2 START WITH 2
MINVALUE 0
NOCYCLE CACHE 10
ORDER;
GRANT SELECT ON seq_id TO cdc_agent;
GRANT SELECT ON seq_id TO myuser;
CREATE TABLE t1
(
id BIGINT NOT NULL
, val1 CHAR(4)
);
GRANT ALL ON t1 TO cdc_agent;
GRANT ALL ON t1 TO myuser;
CREATE PROCEDURE t1_ti_spl_get_seq_id()
REFERENCING NEW AS new_values FOR t1;
LET new_values.id = seq_id.NEXTVAL;
END PROCEDURE;
GRANT EXECUTE ON t1_ti_spl_get_seq_id TO cdc_agent;
GRANT EXECUTE ON t1_ti_spl_get_seq_id TO myuser;
CREATE TRIGGER t1_ti
INSERT ON t1 REFERENCING NEW AS new_ins
FOR EACH ROW WHEN ( USER <> "cdc_agent" )
(
EXECUTE PROCEDURE t1_ti_spl_get_seq_id() WITH TRIGGER REFERENCES
);
向表中插入一些值并检查结果:
-- with user "cdc_agent"
INSERT INTO t1( id, val1 ) VALUES ( 11, 'AAAA' );
INSERT INTO t1( id, val1 ) VALUES ( 13, 'AAAC' );
-- with user "myuser"
INSERT INTO t1( id, val1 ) VALUES ( 1, 'AAAB' );
INSERT INTO t1( id, val1 ) VALUES ( 3, 'AAAD' );
SELECT * FROM t1;
id val1
11 AAAA
13 AAAC
2 AAAB
4 AAAD
推荐阅读
- python - python any() 工作方式不同,为什么 [1,3,5] 中的 any([1,2]) 返回 True 但 ['a','v' 中的 any(['a','b']) 不返回, 'X']?
- ssl - 如何为从主机文件指向的域创建 ssl?
- angular - 使用 Stripe JS 将客户卡保存在 Stripe
- android - 在无障碍服务中禁用 Android 中的触摸屏
- html - Internet Explorer 11 和 Edge 中伪元素的 CSS 指针事件
- javascript - 在 Vue.js 中使用 v-model 进行双向绑定
- sql - 显示学生的名字和他在 Oracle 中注册的课程
- kubernetes - Kubernetes pod 调度到非污染节点
- c# - 为什么 DataContext 无法继承构造为附加属性的对象?
- java - 使用私钥解码 SecretKey