Отдельный триггер увеличения для каждой строки в таблице

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

     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 для каждого значения для column1.

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

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 )
);
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
0
59
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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;

Триггер не идеален для таких целей. Я бы предпочел создать представление с помощью 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 |

Итак, если у меня есть этот сценарий создания таблицы (отредактируйте в основном сообщении для лучшей видимости), как я могу заменить move_number на row_number(), который зависит от game_id?

Jaav 29.05.2018 23:07

@Jaav: вы не можете заменить move_number на row_number или наоборот. row_number - это аналитическая функция docs.oracle.com/cd/B19306_01/server.102/b14200/functions137.‌ htm, вам просто нужно заменить column1 и id в моем запросе, чтобы они содержали правильные столбцы. id может быть ur move_id. Но я не уверен в других столбцах, поскольку вы не показали, что в них содержится.

Kaushik Nayak 30.05.2018 07:54
Ответ принят как подходящий

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

Однако, если вы настаиваете, я бы закодировал это так:

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

Другие вопросы по теме