使用基于视图定义的默认值插入到 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 │
└──────┴───────────┴───────────────┘
你好!假设 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 │
└──────┴───────────┴───────────────┘