CREATE RULE — define una nueva regla de reescritura
CREATE [ OR REPLACE ] RULEnombreAS ONeventoTOnombre_tabla[ WHEREcondición] DO [ ALSO | INSTEAD ] { NOTHING |comando| (comando;comando... ) } dondeeventopuede ser uno de: SELECT | INSERT | UPDATE | DELETE
CREATE RULE define una nueva regla que se aplica a una tabla
o vista especificada.
CREATE OR REPLACE RULE creará una nueva regla,
o reemplazará una regla existente con el mismo nombre para la misma tabla.
El sistema de reglas de PostgreSQL permite definir una
acción alternativa a realizar en inserciones, actualizaciones o eliminaciones en
tablas de la base de datos. En términos generales, una regla hace que se ejecuten
comandos adicionales cuando se ejecuta un comando dado en una tabla dada.
Alternativamente, una regla INSTEAD puede reemplazar un comando dado
por otro, o hacer que un comando no se ejecute en absoluto. Las reglas también se usan
para implementar vistas SQL. Es importante tener en cuenta que una regla es en realidad
un mecanismo de transformación de comandos, o una macro de comando. La transformación
ocurre antes de que comience la ejecución del comando. Si realmente deseas una operación
que se dispare independientemente para cada fila física, probablemente querrás usar un
disparador (trigger) en lugar de una regla. Para obtener más información sobre el sistema de
reglas, consulta la Chapter 39.
Actualmente, las reglas ON SELECT solo se pueden asociar a vistas.
Dicha regla debe llamarse "_RETURN", debe ser una regla
INSTEAD incondicional y debe tener una acción que consista en un único
comando SELECT. Este comando define el contenido visible de la vista.
(La vista misma es básicamente una tabla ficticia sin almacenamiento). Es mejor considerar
dicha regla como un detalle de implementación. Aunque una vista se puede redefinir a través de
CREATE OR REPLACE RULE "_RETURN" AS ..., es mejor estilo usar
CREATE OR REPLACE VIEW.
Puedes crear la ilusión de una vista actualizable definiendo reglas ON INSERT,
ON UPDATE y ON DELETE (o cualquier subconjunto de ellas
que sea suficiente para tus propósitos) para reemplazar las acciones de actualización en la vista
con las actualizaciones apropiadas en otras tablas. Si deseas admitir
INSERT RETURNING y similares, asegúrate de colocar una cláusula
RETURNING adecuada en cada una de estas reglas.
Existe un inconveniente si intentas usar reglas condicionales para actualizaciones complejas de vistas:
debe haber una regla INSTEAD incondicional para cada acción
que desees permitir en la vista. Si la regla es condicional, o no es INSTEAD,
el sistema rechazará los intentos de realizar la acción de actualización, porque piensa que podría
terminar intentando realizar la acción en la tabla ficticia de la vista en algunos casos. Si deseas
manejar todos los casos útiles en reglas condicionales, agrega una regla incondicional
DO INSTEAD NOTHING para asegurar que el sistema entienda que nunca se le llamará
para actualizar la tabla ficticia. Luego, haz que las reglas condicionales sean
no-INSTEAD; en los casos en que se apliquen, se sumarán a la acción predeterminada
INSTEAD NOTHING. (Sin embargo, este método no funciona actualmente para admitir
consultas RETURNING).
Una vista que es lo suficientemente simple como para ser actualizable automáticamente (consulta la CREATE VIEW) no requiere una regla creada por el usuario para ser actualizable. Aunque puedes crear una regla explícita de todos modos, la transformación de actualización automática generalmente superará el rendimiento de una regla explícita.
Otra alternativa que vale la pena considerar es usar disparadores INSTEAD OF
(consulta la CREATE TRIGGER) en lugar de reglas.
nombreEl nombre de la regla a crear. Debe ser distinto del nombre de cualquier otra regla para la misma tabla. Las múltiples reglas en la misma tabla y el mismo tipo de evento se aplican en orden alfabético de sus nombres.
evento
El evento es uno de SELECT, INSERT,
UPDATE o DELETE. Ten en cuenta que un
INSERT que contenga una cláusula ON CONFLICT
no se puede usar en tablas que tengan reglas INSERT o
UPDATE. Considera usar una vista actualizable en su lugar.
nombre_tablaEl nombre (opcionalmente calificado por esquema) de la tabla o vista a la que se aplica la regla.
condición
Cualquier expresión condicional de SQL (que devuelva
boolean). La expresión de condición no puede hacer referencia a ninguna
tabla excepto a NEW y OLD, y no puede contener
funciones de agregación.
INSTEADINSTEAD indica que los comandos deben ejecutarse
en lugar del comando original.
ALSOALSO indica que los comandos deben ejecutarse
además del comando original.
Si no se especifica ALSO ni INSTEAD,
ALSO es el valor por omisión.
comando
El comando o comandos que componen la acción de la regla. Los comandos válidos
son SELECT, INSERT, UPDATE,
DELETE o NOTIFY.
Dentro de la condición y el
comando, se pueden usar los nombres de tabla
especiales NEW y OLD para hacer referencia a los valores
de la tabla referenciada. NEW es válido en reglas ON INSERT
y ON UPDATE para hacer referencia a la nueva fila que se está insertando o
actualizando. OLD es válido en reglas ON UPDATE y
ON DELETE para hacer referencia a la fila existente que se está actualizando
o eliminando.
Debes ser el propietario de una tabla para crear o cambiar reglas para ella.
En una regla para INSERT, UPDATE o DELETE
en una vista, puedes agregar una cláusula RETURNING que devuelva las columnas
de la vista. Esta cláusula se usará para calcular las salidas si la regla se dispara por un comando
INSERT RETURNING, UPDATE RETURNING o
DELETE RETURNING respectivamente. Cuando la regla se dispara por un comando sin
RETURNING, la cláusula RETURNING de la regla se ignorará.
La implementación actual permite solo a las reglas INSTEAD incondicionales contener
RETURNING; además, puede haber a lo sumo una cláusula RETURNING
entre todas las reglas para el mismo evento. (Esto asegura que haya solo una cláusula
RETURNING candidata a ser usada para calcular los resultados).
Las consultas RETURNING en la vista se rechazarán si no hay una cláusula
RETURNING en ninguna regla disponible.
Es muy importante tener cuidado de evitar reglas circulares. Por ejemplo, aunque cada una de las
siguientes dos definiciones de reglas es aceptada por PostgreSQL, el
comando SELECT hará que PostgreSQL reporte un error
debido a la expansión recursiva de una regla:
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;
Actualmente, si la acción de una regla contiene un comando NOTIFY, el comando
NOTIFY se ejecutará incondicionalmente, es decir, el NOTIFY
se emitirá incluso si no hay ninguna fila a la que deba aplicarse la regla. Por ejemplo, en:
CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable; UPDATE mytable SET name = 'foo' WHERE id = 42;
se enviará un evento NOTIFY durante el UPDATE, independientemente
de si hay o no filas que coincidan con la condición id = 42. Esta es una
restricción de implementación que podría corregirse en versiones futuras.
CREATE RULE es una extensión del lenguaje de PostgreSQL,
al igual que todo el sistema de reescritura de consultas.