Можно ли использовать nextval последовательности в качестве значения по умолчанию для поля в таблице в базе данных Infomrix? - PullRequest
0 голосов
/ 16 февраля 2019

У меня есть таблица с именем T1 с идентификатором поля (int8) и последовательностью с именем seq_id.Могу ли я использовать seq_id.nextval в качестве значения по умолчанию для идентификатора в базе данных informix?или другим способом, я могу использовать триггер, чтобы обновить идентификатор перед вставкой с seq_id.nextval?Спасибо заранее, Сайна Мохамадьяри

1 Ответ

0 голосов
/ 16 февраля 2019

В 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
...