Отдельный инкрементный триггер для каждой строки в таблице - PullRequest
0 голосов
/ 29 мая 2018

У меня проблемы с созданием инкрементного триггера для каждой строки в таблице.Что мне нужно, это нумеровать строки в зависимости от одного из столбцов.Например:

     table
column1|column2
    1  |  1
    1  |  2
    2  |  1
    1  |  3
    3  |  1
    2  |  2

Я создал последовательность:

CREATE SEQUENCE inc_seq
MINVALUE 1
START WITH 1
INCREMENT BY 1;

И триггер:

CREATE OR REPLACE TRIGGER inc_on_insert
BEFORE INSERT ON table
FOR EACH ROW
BEGIN
SELECT inc_seq.nextval
INTO :new.column2
FROM dual;
END;

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

Редактировать:

CREATE TABLE moves (
    move_id        NUMBER,
    game_id NOT NULL
        REFERENCES games ( game_id )
            ON DELETE CASCADE,
    move_number    NUMBER NOT NULL,
    stages_count   NUMBER DEFAULT 1,
    CONSTRAINT move_pk PRIMARY KEY ( move_id ),
    CONSTRAINT moves_const_1 UNIQUE ( game_id,
                                      move_number,
                                      stages_count )
);

Ответы [ 3 ]

0 голосов
/ 29 мая 2018

Триггер не идеален для таких целей.Я предпочел бы создать представление, используя row_number().Вы по-прежнему можете использовать триггер / последовательность для создания столбца id для таблицы.

CREATE
    OR replace VIEW t_view AS
SELECT column1
    ,row_number() OVER (
        PARTITION BY column1 ORDER BY id --id generated using your trigger
        ) AS column2
FROM t
ORDER BY id;

Демо

select * from t_view;

| COLUMN1 | COLUMN2 |
|---------|---------|
|       1 |       1 |
|       1 |       2 |
|       2 |       1 |
|       1 |       3 |
|       3 |       1 |
|       2 |       2 |
0 голосов
/ 29 мая 2018

Я придерживаюсь мнения Каушика и не буду использовать триггер для этой цели.Например, что произойдет, если строка будет удалена?

Если вы настаиваете на этом, я бы написал ее так:

CREATE TABLE mytable (column1 NUMBER, column2 NUMBER);

CREATE OR REPLACE TRIGGER inc_on_insert
BEFORE INSERT ON mytable
FOR EACH ROW
BEGIN
  SELECT COUNT(*)+1 INTO :NEW.column2 
    FROM mytable 
   WHERE column1=:NEW.column1;
END;
/

INSERT INTO mytable(column1) VALUES (5);
SELECT * FROM mytable;
5 1

INSERT INTO mytable(column1) VALUES (5);
SELECT * FROM mytable;
5 1
5 2

INSERT INTO mytable(column1) VALUES (6);
SELECT * FROM mytable;
5 1
5 2
6 1

INSERT INTO MYTABLE(COLUMN1) VALUES (5);
SELECT * FROM mytable;
5 1
5 2
6 1
5 3
0 голосов
/ 29 мая 2018

Пожалуйста, попробуйте что-то вроде:

CREATE OR REPLACE TRIGGER inc_on_insert
BEFORE INSERT ON table
FOR EACH ROW

BEGIN
select count(1) into thereiscolumn1 from table where column1 = :new.column1 and rownum=1;
if thereiscolumn1 > 0 THEN
    SELECT (MAX(column2) + 1 ) INTO :new.column2 from table WHERE column1 = :new.column1
ELSE
    SELECT 1 INTO :new.column2 FROM dual;
END IF;

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