CREATE RULE

CREATE RULE — определить новое правило перезаписи


Синтаксис

CREATE [ OR REPLACE ] RULE имя AS ON событие
    TO имя_таблицы [ WHERE условие ]
    DO [ ALSO | INSTEAD ] { NOTHING | команда | ( команда ; команда ... ) }

где событием может быть:

    SELECT | INSERT | UPDATE | DELETE

Описание

Команда CREATE RULE определяет новое правило, применяемое к указанной таблице или представлению. CREATE OR REPLACE RULE либо создаст новое правило, либо заменит существующее правило с тем же именем для той же таблицы.

Система правил QHB позволяет определить альтернативное действие, которое будет выполняться при добавлении, изменении или удалении в таблицах базы данных. Грубо говоря, когда выполняется данная команда на данной таблице, правило вызывает выполнение дополнительных команд. В качестве альтернативы правило INSTEAD может заменить данную команду другой или привести к тому, что команда не будет выполняться вообще. Правила также используются для реализации представлений SQL. Важно понимать, что правило — это действительно механизм преобразования команд, или командный макрос. Преобразование происходит до начала выполнения команды. Если вам действительно нужна операция, которая срабатывает независимо для каждой физической строки, вероятно, лучше использовать триггер, а не правило.

На данный момент правила ON SELECT должны быть безусловными, с указанием INSTEAD, и их действия должны состоять из единственной команды SELECT. Таким образом, правило ON SELECT по сути превращает таблицу в представление, видимым содержимым которого являются строки, возвращаемые заданной в правиле командой SELECT, а не данные, хранящиеся в таблице (если они есть). Считается все же, что для этой цели лучше пользоваться командой CREATE VIEW, а не создавать реальную таблицу и затем определять для нее правило ON SELECT.

Чтобы заменить операции изменения в представлении соответствующими изменениями в других таблицах, можно создать иллюзию изменяемого представления путем определения правил ON INSERT, ON UPDATE и ON DELETE (или любого подмножество правил, достаточного для ваших целей). Если желаете поддержать операторы вроде INSERT RETURNING и пр., то не забудьте поместить в каждое из этих правил подходящее предложение RETURNING.

При попытке использовать условные правила для изменения сложных представлений возникает одна загвоздка: для каждого действия, которое вы хотите разрешить для представления, необходимо определить безусловное правило INSTEAD. Если правило условное или не типа INSTEAD, система отвергнет попытки выполнить изменения, предполагая, что в некоторых случаях они могут свестись к попыткам провести операцию с фиктивной таблицей представления. Если вы хотите обрабатывать все полезные случаи изменений в условных правилах, добавьте безусловное правило DO INSTEAD NOTHING, гарантирующее, что система поймет, что ей никогда не придется изменять фиктивную таблицу. Затем создайте условные правила без свойства INSTEAD; в тех случаях, когда они будут применяться, их действия будут добавлены к действию по умолчанию INSTEAD NOTHING. (Однако в настоящее время этот способ не подходит для реализации запросов RETURNING.)

Примечание
Представление достаточно простое, чтобы изменяться автоматически (см. CREATE VIEW), не требует для этого созданного пользователем правила. Хотя все равно можно создать явное правило, но автоматическое преобразование изменения в общем и целом будет работать лучше.

Еще одна альтернатива, которую стоит рассмотреть, — это использование вместо правил триггеров INSTEAD OF (см. справочную страницу команды CREATE TRIGGER).


Параметры

имя

Имя создаваемого правила. Должно отличаться от имени любого другого правила для той же таблицы. Несколько правил для одной и той же таблицы и одного и того же типа событий применяются в алфавитном порядке имен.

событие

Тип события: SELECT, INSERT, UPDATE или DELETE. Обратите внимание, что команду INSERT с предложением ON CONFLICT нельзя использовать в таблицах, для которых определено правило INSERT или UPDATE. Вместо этого рассмотрите возможность использования изменяемого представления.

имя_таблицы

Имя таблицы или представления, к которым будет применяться правило (может быть дополнено схемой).

условие

Любое выражение условия SQL (возвращающее boolean). Выражение условия не может ссылаться ни на какие таблицы, кроме NEW и OLD, и не может содержать агрегатных функций.

INSTEAD

INSTEAD показывает, что команды должны выполняться вместо исходной команды.

ALSO

ALSO показывает, что команды должны выполняться в дополнение к исходной команде.

Если ни INSTEAD, ни ALSO не заданы, по умолчанию применяется ALSO.

команда

Команда или команды, составляющие действие правила. Допустимыми командами являются SELECT, INSERT, UPDATE, DELETE и NOTIFY.

В параметрах условие и команда для обращения к значениям в соответствующей таблице могут использоваться имена специальных таблиц NEW и OLD. 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. (Это гарантирует, что существует только одно подходящее предложение RETURNING, которое и будет использоваться для вычисления результатов.) Запросы с RETURNING к представлению будут отклонены, если в имеющихся у него правилах нет ни одного предложения RETURNING.

Очень важно позаботиться о том, чтобы правила не зацикливались. Например, хотя каждое из следующих двух определений правил принимается QHB, команда SELECT приведет к тому, что QHB сообщит об ошибке из-за рекурсивного расширения правила:

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;

событие NOTIFY будет отправлено во время выполнения UPDATE независимо от того, есть ли строки, соответствующие условию id = 42. Это ограничение реализации, которое может быть исправлено в будущих выпусках.


Совместимость

Команда CREATE RULE является языковым расширением QHB, как и вся система перезаписи запросов.


См. также

ALTER RULE, DROP RULE