Перейти к основному содержимому

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, то система все равно отклонит попытку выполнения команды, так как сочтет возможным, что операция будет направлена на фиктивную таблицу представления. Чтобы этого избежать:

  1. Добавьте безусловное правило DO INSTEAD NOTHING — это даст системе понять, что операция над представлением не требуется.
  2. Задайте все условные правила без свойства 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, как и вся система переписывания запросов.

Смотрите также

ALTER RULE, DROP RULE