插入表中,返回id,然后插入另一个存储标识为

时间:2016-08-10 22:03:28

标签: postgresql many-to-many sql-insert

我有以下三个表: 请注意,下面的DDL是由Django生成的模型,然后在创建后从Postgresql中删除。因此,修改表不是一种选择。

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?更具体地说,我有一个教师表,老师可以教授与多个年级相关的内容,我正在尝试编写插入语句以开始填充我的数据库。这样我才宣布教师的名字,以及他们所涉及的成绩。

例如,如果我的教师只属于一个年级,那么插入语句就像这样。

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年级相关

留给我这张表为parentTeacherCon_teacher_grade

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

这就是我目前(成功)插入教师表的方法。

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

然后进入成绩表

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)。

1 个答案:

答案 0 :(得分:0)

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

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