触发创建父元素并在Postgresql中检索ID

时间:2019-03-11 23:20:53

标签: sql postgresql triggers

我创建了以下表格:

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行数据包的形式提交预测,这些预测应具有相同的提交ID。

我正在尝试创建一个在插入之前运行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答案,事件的顺序如下:

用户在public.predictions中插入1000行:

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 */

他不知道要在这些行中插入哪个subscription_id,实际上,该预测数据包的submissions行还不存在,因此在创建将执行以下操作的submit中的行之前,将运行触发器:

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.name,如何在执行触发器期间检索team.id?

谢谢! 问候

1 个答案:

答案 0 :(得分:0)

触发器功能,用于行级触发器has access to the old and new state of the table

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