插入到 table、return id,然后插入到另一个具有存储 id 的 table

Insert into table, return id and then insert into another table with stored id

我有以下三个table: 请注意,下面的 DDL 来自 Django 生成的模型,然后在创建后从 Postgresql 中抓取。所以修改 tables 不是一个选项。

CREATE TABLE "parentTeacherCon_grade"
(
    id INTEGER PRIMARY KEY NOT NULL,
    "currentGrade" VARCHAR(2) NOT NULL
);
CREATE TABLE "parentTeacherCon_parent"
(
    id INTEGER PRIMARY KEY NOT NULL,
    name VARCHAR(50) NOT NULL,
    grade_id INTEGER NOT NULL
);
CREATE TABLE "parentTeacherCon_teacher"
(
    id INTEGER PRIMARY KEY NOT NULL,
    name VARCHAR(50) NOT NULL
);
CREATE TABLE "parentTeacherCon_teacher_grade"
(
    id INTEGER PRIMARY KEY NOT NULL,
    teacher_id INTEGER NOT NULL,
    grade_id INTEGER NOT NULL
);
ALTER TABLE "parentTeacherCon_parent" ADD FOREIGN KEY (grade_id) REFERENCES "parentTeacherCon_grade" (id);
CREATE INDEX "parentTeacherCon_parent_5c853be8" ON "parentTeacherCon_parent" (grade_id);
CREATE INDEX "parentTeacherCon_teacher_5c853be8" ON "parentTeacherCon_teacher" (grade_id);
ALTER TABLE "parentTeacherCon_teacher_grade" ADD FOREIGN KEY (teacher_id) REFERENCES "parentTeacherCon_teacher" (id);
ALTER TABLE "parentTeacherCon_teacher_grade" ADD FOREIGN KEY (grade_id) REFERENCES "parentTeacherCon_grade" (id);
CREATE UNIQUE INDEX "parentTeacherCon_teacher_grade_teacher_id_20e07c38_uniq" ON "parentTeacherCon_teacher_grade" (teacher_id, grade_id);
CREATE INDEX "parentTeacherCon_teacher_grade_d9614d40" ON "parentTeacherCon_teacher_grade" (teacher_id);
CREATE INDEX "parentTeacherCon_teacher_grade_5c853be8" ON "parentTeacherCon_teacher_grade" (grade_id);

我的问题是:如何在没有跟踪 ID 的情况下编写插入语句(或多个语句)?更具体地说,我有一位老师 table,老师可以教授与多个年级相关的内容,我正在尝试编写插入语句以开始填充我的数据库。这样一来,我只声明了一位老师的名字,以及与他们相关的成绩。

例如,如果我有一位只属于一个年级的老师,那么插入语句如下所示。

INSERT INTO "parentTeacherCon_teacher" (name, grade_id) VALUES ('foo bar', 1  );

其中列举了 K-12 年级 0,12

但需要做类似的事情(我意识到这行不通)

INSERT INTO "parentTeacherCon_teacher" (name, grade_id) VALUES ('foo bar', (0,1,3)  );

表示该老师与K、1、3年级有关

留给我 table 用于 parentTeacherCon_teacher_grade

+----+------------+----------+
| id | teacher_id | grade_id |
+----+------------+----------+
|  1 |          3 |        0 |
|  2 |          3 |        1 |
|  3 |          3 |        3 |
+----+------------+----------+

这就是我目前(成功)插入到 Teacher Table 中的方式。

INSERT INTO public."parentTeacherCon_teacher" (id, name) VALUES (3, 'Foo Bar');

然后进入年级table

INSERT INTO public.parentTeacherCon_teacher_grade (id, teacher_id, grade_id) VALUES (1, 3, 0);
INSERT INTO public.parentTeacherCon_teacher_grade (id, teacher_id, grade_id) VALUES (2, 3, 1);
INSERT INTO public.parentTeacherCon_teacher_grade (id, teacher_id, grade_id) VALUES (3, 3, 3);

更多信息。 Here is a diagram of the database

我尝试过的其他东西。

WITH i1 AS (INSERT INTO "parentTeacherCon_teacher" (name) VALUES ('foo bar')
RETURNING id) INSERT INTO "parentTeacherCon_teacher_grade"
  SELECT
    i1.id
    , v.val
  FROM i1, (VALUES (1), (2), (3)) v(val);

然后我得到这个错误。

[2016-08-10 16:07:46] [23502] ERROR: null value in column "grade_id" violates not-null constraint

详细信息:失败行包含 (6, 1, null)。

如果你想在一个语句中插入所有三行,你可以使用:

INSERT INTO "parentTeacherCon_teacher" (name, grade_id) 
    SELECT 'foo bar', g.grade_id
    FROM (SELECT 0 as grade_id UNION ALL SELECT 1 UNION ALL SELECT 3) g;

或者,如果您愿意:

INSERT INTO "parentTeacherCon_teacher" (name, grade_id) 
    SELECT 'foo bar', g.grade_id
    FROM (VALUES (0), (2), (3)) g(grade_id);

编辑:

在 Postgres 中,您可以将数据修改语句作为 CTE:

WITH i as (
      INSERT INTO public."parentTeacherCon_teacher" (id, name)
          VALUES (3, 'Foo Bar')
          RETURNING *
     )
INSERT INTO "parentTeacherCon_teacher" (name, teacher_id, grade_id) 
    SELECT 'foo bar', i.id, g.grade_id
    FROM (VALUES (0), (2), (3)) g(grade_id) CROSS JOIN
         i