В 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)
);
Я нашел 2 способа использования этой процедуры.Общая процедура, которая возвращает последовательность NEXTVAL
, и триггерная процедура, которая назначает последовательность 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 ).
EDIT 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