триггер для создания родительского элемента и получения идентификатора в postgresql - PullRequest
1 голос
/ 12 марта 2019

Я создал следующие таблицы:

CREATE TABLE IF NOT EXISTS public.teams (
    id SERIAL PRIMARY KEY,
    name VARCHAR(64) NOT NULL UNIQUE
) WITH (OIDS = FALSE);

CREATE TABLE IF NOT EXISTS public.submissions (
    id SERIAL PRIMARY KEY,
    team_id INTEGER REFERENCES public.teams NOT NULL,
    records_num INTEGER NOT NULL,
    timestamp TIMESTAMP NOT NULL
) WITH (OIDS = FALSE);

CREATE TABLE IF NOT EXISTS public.predictions (
    id SERIAL PRIMARY KEY,
    submission_id INTEGER REFERENCES public.submissions NOT NULL,
    customer INTEGER REFERENCES public.real NOT NULL,
    date DATE NOT NULL,
    billing NUMERIC(20, 2) NOT NULL
) WITH (OIDS = FALSE);

CREATE TABLE IF NOT EXISTS public.real (
    customer INTEGER PRIMARY KEY,
    date DATE NOT NULL,
    billing NUMERIC(20, 2) NOT NULL
) WITH (OIDS = FALSE);

Отношение для представления-предсказания одно-ко-многим; пользователи будут отправлять прогнозы в пакетах по 1000 строк, которые должны получить одинаковый идентификатор отправки.

Я пытаюсь создать триггер, выполняющий ПЕРЕД прогнозами INSERT ON, который создает строку представлений. Это то, что я до сих пор:

CREATE OR REPLACE FUNCTION insert_submission() RETURNS TRIGGER AS
$$
BEGIN
    INSERT INTO submissions(team_id, records_num, timestamp)
    VALUES (1, 1, '2018-04-21 00:00:00'); /*example values, need to fill with dynamically assigned ones, specially for records_num and team_id*/
    RETURN NULL;
END
$$ LANGUAGE plpgsql;
DROP TRIGGER trigger_submission ON public.predictions;
CREATE TRIGGER trigger_submission BEFORE INSERT ON predictions
EXECUTE PROCEDURE insert_submission();

Итак, мои вопросы:

  1. Как мне получить вновь созданный файл submissions.id для строки, вставленной триггером, чтобы добавить ее ко всем строкам, вставленным в прогнозы пользователем? Нужно ли для этого запускать другой триггер ПОСЛЕ ВСТАВКИ?

РЕДАКТИРОВАТЬ: чтобы уточнить следующий ответ @bignose, последовательность событий будет выглядеть следующим образом:

Пользователь вставляет 1000 строк в public.predictions:

INSERT INTO predictions(customer, date, billing)
VALUES
(1, '2018-01-05', 543.42),
(4, '2018-04-02', 553.21),
...
(423, '2019-11-18', 38.87) /* 1000th row */

Он не знает, какой submission_id вставлять в эти строки, и действительно, строка отправки для этого пакета предсказаний еще не существует, поэтому перед запуском запускается триггер для создания строки в представлениях, которая будет выполнять что-то вроде этого:

INSERT INTO public.submisssions(team_id, records_num, timestamp)
VALUES (
4, /* I will need something to retrieve team_id here */
1000, /* I will need something to count the rows of the insert that triggered this */
NOW() /* convert to timestamp */
)

Этот последний запрос должен возвращать значение public.submission.id, которое он только что создал, для вставки, запрошенной пользователем, так что в итоге он будет выглядеть примерно так:

INSERT INTO predictions(customer, date, billing)
VALUES
(@submission_id, 1, '2018-01-05', 543.42),
(@submission_id, 4, '2018-04-02', 553.21),
...
(@submission_id, 423, '2019-11-18', 38.87) /* 1000th row */

Где @submission_id должно быть значением, полученным из триггера (и некоторых для всех 1000 строк)

  1. Как можно подсчитать строки, вставленные пользователем, чтобы использовать их в качестве значения для submissions.records_num?

  2. Как я могу получить team.id для вставки во время выполнения триггера, если я заранее знаю team.name?

Спасибо! С уважением

1 Ответ

0 голосов
/ 12 марта 2019

Функция триггера, при использовании для триггера уровня строки, имеет доступ к старому и новому состоянию таблицы .

CREATE OR REPLACE FUNCTION insert_submission() RETURNS TRIGGER AS
$$
BEGIN
    INSERT INTO submissions(team_id, records_num, timestamp)
    VALUES (NEW.foo, NEW.bar, '2018-04-21 00:00:00');
    RETURN NULL;
END
$$ LANGUAGE plpgsql;

Из описания не ясно, какие поля вы ожидаете получить из строки, которая вызывает эту функцию. Поэтому вам нужно заменить NEW.foo и NEW.bar ссылками на поля в состоянии строки NEW.

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