CREATE RULE
Эта страница переведена при помощи нейросети GigaChat.
CREATE RULE
— создание правила перезаписи.
Синтаксис
CREATE [ OR REPLACE ] RULE name AS ON event
TO table_name [ WHERE condition ]
DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }
where event can be one of:
SELECT | INSERT | UPDATE | DELETE
Описание
CREATE RULE
создает новое правило, которое применяется к указанной таблице или представлению. Команда CREATE OR REPLACE RULE
создает новое правило либо заменяет уже существующее с тем же именем для той же таблицы.
Система правил PostgreSQL позволяет задавать альтернативное поведение для операций INSERT
, UPDATE
и DELETE
в таблицах. Грубо говоря, правило автоматически вызывает дополнительные команды при выполнении основной команды.
В качестве альтернативы, правило INSTEAD
может полностью заменить исходную команду на другую или отменить ее выполнение.
Правила также активно используются для реализации представлений.
Важно понимать, что правило — это механизм преобразования команд, своего рода макрос. Это преобразование происходит до того, как команда начнет выполняться.
Если нужно выполнять действия для каждой строки отдельно, используйте триггеры, а не правила. Подробнее о правилах описано в разделе «Система правил».
На данный момент правила ON SELECT
можно создавать только для представлений. При этом такое правило должно соответствовать следующим требованиям:
- его имя должно быть
_RETURN
; - оно должно быть безусловным правилом
INSTEAD
; - оно должно выполнять одну единственную команду
SELECT
.
Эта команда SELECT
определяет, какие строки будут отображаться при обращении к представлению. Сами представления при этом являются "пустыми" структурами — у них нет физического хранения данных.
Такие правила стоит рассматривать как внутреннюю реализацию представлений. Хотя технически можно изменить представление через команду CREATE OR REPLACE RULE "_RETURN" AS ...
,
более правильным и понятным решением будет использовать CREATE OR REPLACE VIEW
.
Можно создать впечатление, что представление поддерживает обновление, если задать для него правила ON INSERT
, ON UPDATE
и ON DELETE
(или любую их комбинацию),
которые будут заменять действия над представлением соответствующими действиями с другими таблицами.
Если нужно поддерживать команды вроде INSERT RETURNING
и подобные, убедитесь, что каждое из этих правил включает соответствующий оператор RETURNING
.
Однако есть одна важная особенность: если используются условные правила для обработки сложных обновлений представлений,
то для каждого действия (INSERT
, UPDATE
, DELETE
), которое нужно разрешить, должно быть хотя бы одно безусловное правило INSTEAD
.
Если правило содержит условие (WHERE
) или не является INSTEAD
, то система все равно отклонит попытку выполнения команды, так как сочтет возможным, что операция будет направлена на фиктивную таблицу представления. Чтобы этого избежать:
- Добавьте безусловное правило
DO INSTEAD NOTHING
— это даст системе понять, что операция над представлением не требуется. - Задайте все условные правила без свойства
INSTEAD
, чтобы они дополняли действие по умолчанию (INSTEAD NOTHING
), в тех случаях, когда они применяются, они добавляют к действию по умолчаниюINSTEAD NOTHING
.
Этот метод в настоящее время не поддерживает запросы RETURNING
.
Если представление достаточно простое, PostgreSQL сможет сделать его обновляемым автоматически (смотрите CREATE VIEW). В этом случае не нужно создавать свои правила вручную — автоматическое преобразование таких операций будет, как правило, более эффективным, чем правила, написанные вручную.
Альтернативно вместо правил можно использовать INSTEAD OF
триггеры (смотрите CREATE TRIGGER),
и в некоторых случаях это будет более удобным и надежным решением.
Параметры
name
- Задает имя правила, которое должно быть создано. Оно должно быть уникальным среди всех правил для данной таблицы.
Если для одной таблицы существует несколько правил одного и того же типа события, то они будут выполняться в алфавитном порядке по имени правила.
event
- Задает тип события, при наступлении которого правило будет срабатывать:
SELECT
,INSERT
,UPDATE
,DELETE
.Если команда
INSERT
содержит конструкциюON CONFLICT
, то такая команда не может использоваться для таблиц, у которых определены правилаINSERT
илиUPDATE
. В таких случаях рекомендуется использовать обновляемое представление вместо таблицы с правилами.
table_name
- Указывает имя таблицы или представления, при необходимости дополненное схемой, к которому применяется правило.
condition
- Задает SQL-условие (возвращающее
boolean
), при выполнении которого правило срабатывает. Выражение условия не может ссылаться ни на какие таблицы, кромеNEW
иOLD
, и не может содержать агрегатные функции.
INSTEAD
- Указывает, что команды, описанные в правиле, должны полностью заменить исходные команды.
ALSO
- Указывает, что команды из правила будут выполнены в дополнение к исходной команде.
Если не указано ни
ALSO
, ниINSTEAD
, то по умолчанию действует поведениеALSO
.
command
- Задает команду или список команд, которые должны быть выполнены при срабатывании правила. Допустимыми командами являются
SELECT
,INSERT
,UPDATE
,DELETE
,NOTIFY
.
Внутри условий condition
и команд command
можно использовать специальные имена таблиц:
NEW
ссылается на новую строку, используемую в правилахON INSERT
иON UPDATE
;OLD
ссылается на исходную строку, применимо для правилON UPDATE
иON DELETE
.
Примечания
Чтобы выполнить эту команду, необходимо быть владельцем таблицы, к которому применяется правило.
В правилах для INSERT
, UPDATE
и DELETE
, созданных для представлений, можно добавить оператор RETURNING
, который возвращает столбцы представления. Этот оператор будет использоваться для вычисления выходных данных, если правило вызвано командой INSERT ... RETURNING
, UPDATE ... RETURNING
или DELETE ... RETURNING
соответственно.
Когда правило вызывается командой без RETURNING
, предложение RETURNING
правила будет игнорироваться. Оператор RETURNING
можно использовать только в безусловных правилах INSTEAD
. Допускается не более одного правила с RETURNING
на каждое событие (INSERT
, UPDATE
, DELETE
). Если нет ни одного правила с RETURNING
, соответствующие запросы к представлению будут отклонены.
Необходимо избегать создания циклических (рекурсивных) правил, так как они могут вызывать бесконечную подстановку и приводить к ошибке. Например, хотя каждое из следующих двух определений правил принимается PostgreSQL, команда SELECT
приведет к тому, что PostgreSQL сообщит об ошибке из-за рекурсивного расширения правила:
CREATE RULE "_RETURN" AS
ON SELECT TO t1
DO INSTEAD
SELECT * FROM t2;
CREATE RULE "_RETURN" AS
ON SELECT TO t2
DO INSTEAD
SELECT * FROM t1;
SELECT * FROM t1;
В настоящее время, если в теле правила указана команда NOTIFY
, она будет выполняться всегда, даже если правило не применяется ни к одной строке. Пример:
CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable;
UPDATE mytable SET name = 'foo' WHERE id = 42;
Даже если строка с id = 42
не найдена, уведомление NOTIFY
все равно будет отправлено. Это ограничение текущей реализации и в будущем может быть изменено.
Совместимость
CREATE RULE
является расширением языка PostgreSQL, как и вся система переписывания запросов.