Привет! Скажем, vehicle
может быть типа «автомобиль», «грузовик» или «мотоцикл». У каждого автомобиля есть шнур top_speed
(в км / ч) и шнур 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');
Моя проблема в том, что я уже вставляю в представление под названием «автомобиль» ... зачем мне нужно указывать этот type = 'car'
?
Если я опущу столбец type
из этого запроса вставки, я получу сообщение об ошибке, что столбец type
не может содержать NULL
. Похоже, что postgres не будет опускать значения по умолчанию, даже если они мог будут извлечены из определения представления.
Есть ли способ заставить postgres посмотреть определение представления, чтобы предоставить значения по умолчанию для пропущенных столбцов в запросах INSERT
?
Postgres может запретить вам вставлять в представление строки, которые не были бы видны в представлении. Синтаксис - WITH CHECK OPTION
в конце CREATE VIEW
.
Вывод значений столбца из предложения where
представления не поддерживается. Вы можете смоделировать это с помощью instead of insert
триггер:
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 есть очень мощный система правил.
В дополнение к вашему коду:
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 │
└──────┴───────────┴───────────────┘