使用 Postgresql,我的表具有父/子或一般/詳細關系,有點像面向物件的繼承:
CREATE TYPE person_kinds AS ENUM ('student', 'teacher');
CREATE TABLE person(id serial primary key, kind person_kinds, name text);
CREATE TABLE teacher(person_id integer primary key references person(id), subject text);
CREATE TABLE student(person_id integer primary key references person(id), grade integer);
也就是說,person 表包含了一個人共有的所有東西,并保留了一個型別標簽。子表通過根據型別添加額外的列來親自細化資訊;例如,一個老師教一門學科,一個學生可能有一個成績。這個表結構是給定的,我不能改變它。(例如,我不認為我可以添加繼承,但我不相信這會有所幫助)
現在我有一個包含學生資料的臨時表,它是上述的“平面”版本。例如
CREATE TABLE tmp_table(kind person_kinds, name text, grade integer);
INSERT INTO tmp_table(kind, name, grade)
VALUES ('student', 'Chris', 2),('student','Lara',1),('student','Izzy',3);
我的問題是,如何將臨時表中的資料插入到上述表中?我遇到了困難,因為學生表的插入需要 person-id 作為外鍵,而且學生表沒有任何“區分”列,所以我不能加入任何東西。
我嘗試了以下幾方面的事情:
with inserted_persons as
(
insert into person(type, name)
select type, name
from tmp_table
returning id --I sadly cannot return any columns from tmp_table here
)
insert into student(person_id, grade)
select
p.id, t.grade
from
-- I don't have a column to join on, and the implicit join here
-- is wrong as it crosses the tmp_table with the inserted_persons
inserted_persons as p,
tmp_table as t
uj5u.com熱心網友回復:
我會通過為學生創建一個視圖來解決這個問題:
CREATE VIEW v_student AS
SELECT person.id, person.name, student.grade
FROM person
JOIN student
ON person.id = student.person_id
WHERE person.kind = 'student';
和一個INSTEAD OF INSERT觸發器:
CREATE FUNCTION ins_student() RETURNS trigger
LANGUAGE plpgsql AS
$$DECLARE
v_id integer;
BEGIN
INSERT INTO person (kind, name)
VALUES ('student', NEW.name)
RETURNING id INTO v_id;
INSERT INTO student (person_id, grade)
VALUES (v_id, NEW.grade);
RETURN NEW;
END;$$;
CREATE TRIGGER ins_student INSTEAD OF INSERT ON v_student
FOR EACH ROW EXECUTE FUNCTION ins_student();
可以這樣使用:
INSERT INTO v_student (name, grade)
SELECT name, grade FROM tmp_table
WHERE kind = 'student';
TABLE person;
id │ kind │ name
════╪═════════╪═══════
1 │ student │ Chris
2 │ student │ Lara
3 │ student │ Izzy
(3 rows)
TABLE student;
person_id │ grade
═══════════╪═══════
1 │ 2
2 │ 1
3 │ 3
(3 rows)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/464759.html
標籤:sql PostgreSQL 类表继承
上一篇:當聚合來自多個內部查詢的資料時,如何避免冗長和簡化?
下一篇:將行級安全策略繼承給子/關系
