使用基于视图定义的默认值插入到 postgres 视图中

Insert into postgres view using defaults based on view definition

你好!假设 vehicle 可以是 "car"、"truck" 或 "motorcycle" 类型。每辆车都有一个 top_speed(在 km/h 中)和一个 license_plate 字符串。

例如

CREATE TABLE vehicle (
  type VARCHAR(20) NOT NULL,
  top_speed INTEGER NOT NULL,
  license_plate VARCHAR(10) NOT NULL
);

INSERT INTO vehicle (type, top_speed, license_plate)
  VALUES
    ('car', 120, 'abc123'),
    ('truck', 110, 'def456'),
    ('motorcycle', 140, 'ghi789');

现在为每种类型的车辆添加视图:

CREATE VIEW car AS (SELECT * FROM vehicle WHERE type='car');
CREATE VIEW truck AS (SELECT * FROM vehicle WHERE type='truck');
CREATE VIEW motorcycle AS (SELECT * FROM vehicle WHERE type='motorcycle');

这一切都很好,很漂亮。但是当我尝试插入这些视图时,我 运行 陷入了一种不舒服的境地:

INSERT INTO car (type, top_speed, license_plate)
  VALUES
    ('car', 160, 'v4n1ty');

我的问题是我已经插入到一个名为 "car" 的视图中...为什么我还要费心去指定 type = 'car'

如果我从这个插入查询中省略 type 列,我会得到一个错误,指出 type 列不允许包含 NULL。似乎 postgres 不会默认省略值,即使它们 可以 从视图的定义中收集。

有没有办法让 postgres 查看视图的定义,以便为 INSERT 查询中省略的列提供默认值?

Postgres 可以阻止您将在视图中不可见的行插入到视图中。语法是 CREATE VIEW.

末尾的 WITH CHECK OPTION

不支持从视图的 where 子句中推断列值。你可以用 instead of insert trigger:

模拟它
CREATE FUNCTION insertCar() RETURNS trigger AS $$
BEGIN
    INSERT INTO vehicle
        (type, top_speed, license_plate)
    VALUES
        ('car', new.top_speed, new.license_plate);
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER insertCarTrigger INSTEAD OF INSERT ON car
  FOR EACH ROW EXECUTE PROCEDURE insertCar();

PostgreSQL中有非常强大的rule system

除您的代码外:

create rule car_insert as on insert to car do instead
  insert into vehicle(type, top_speed, license_plate)
    values('car', new.top_speed, new.license_plate);

insert into car(top_speed, license_plate) values(160,'v4n1ty');

table car;
┌──────┬───────────┬───────────────┐
│ type │ top_speed │ license_plate │
├──────┼───────────┼───────────────┤
│ car  │       120 │ abc123        │
│ car  │       160 │ v4n1ty        │
└──────┴───────────┴───────────────┘