Siéntete libre de divulgar nuestro sitio y códigos con tus amigos, necesitamos tu ayuda para ampliar nuestra comunidad.
Solución:
Uno de los casos de uso de las REGLAS son las vistas actualizables (aunque eso cambia en la versión 9.1, ya que esa versión introduce INSTEAD OF activadores para las vistas).
Otra buena explicación se puede encontrar en el manual:
Para las cosas que pueden implementar ambos, cuál es mejor depende del uso de la base de datos. Se dispara un disparador para cualquier fila afectada una vez. Una regla manipula la consulta o genera una consulta adicional. Por lo tanto, si se ven afectadas muchas filas en una instrucción, es probable que una regla que emita un comando adicional sea más rápida que un activador que se invoca para cada fila y debe ejecutar sus operaciones muchas veces. Sin embargo, el enfoque de disparador es conceptualmente mucho más simple que el enfoque de regla, y es más fácil para los novatos hacerlo bien.
(Tomado de: http://www.postgresql.org/docs/current/static/rules-triggers.html)
Aquí se muestran algunos problemas con las reglas: http://www.depesz.com/index.php/2010/06/15/to-rule-or-not-to-rule-that-is-the-question/ (para Por ejemplo, si se incluye una función random() en una consulta, es posible que se ejecute dos veces y devuelva valores diferentes).
El mayor inconveniente de las reglas es que la gente no comprender ellos.
Por ejemplo, uno podría pensar que teniendo la regla:
CREATE OR REPLACE RULE protect_data AS
ON UPDATE TO exampletable -- another similar rule for DELETE
WHERE OLD.type = 'protected'
DO INSTEAD NOTHING;
Significará que si voy a emitir:
update exampletable set whatever = whatever + 1 where type = 'protected'
No se ejecutará ninguna consulta. Lo cual no es true. La consulta voluntad se ejecutará, pero se ejecutará en una versión modificada, con una condición adicional.
Además, las reglas rompen algo muy útil, que es la cláusula de devolución:
$ update exampletable set whatever = whatever + 1 where type = 'normal' returning *;
ERROR: cannot perform UPDATE RETURNING on relation "exampletable"
HINT: You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause.
Para envolverlo, si realmente tiene que usar vistas de escritura y está usando PostgreSQL anterior a 9.1, debe puede que tener una razón válida para usar reglas.
En todos los demás casos, lo más probable es que te dispares en un pie, incluso si no lo ves de inmediato.
He tenido algunas experiencias amargas con las reglas cuando se trata de funciones volátiles (si la memoria no me falla, la publicación del blog de depesz destaca algunas de ellas).
También rompí la integridad referencial al usarlos debido al momento en que se activan los activadores de tecla fkey:
CREATE OR REPLACE RULE protected_example AS
ON DELETE TO example
WHERE OLD.protected
DO INSTEAD NOTHING;
… luego agregue otra tabla y haga referencia de ejemplo a esa tabla con una cascada de eliminación externa key. Luego, elimine * de esa tabla… y retroceda horrorizado.
Informé el problema anterior como un error, que se descartó como una característica/caso de borde necesario. Solo unos meses después entendí por qué podría ser eso, es decir, el activador fkey hace su trabajo, y luego la regla se activa y hace lo suyo, pero el activador fkey no verificará que su trabajo se haya realizado correctamente por razones de rendimiento. .
El caso de uso práctico donde todavía uso reglas es cuando un BEFORE
El disparador que manipula previamente los datos (el estándar SQL dice que no está permitido, pero Postgres lo complacerá felizmente) puede resultar en la manipulación previa de las filas afectadas y, por lo tanto, cambiar su ctid (es decir, se actualiza dos veces o no se elimina porque un la actualización invalidó la eliminación).
Esto da como resultado que Postgres devuelva un número incorrecto de filas afectadas, lo cual no es gran cosa hasta que supervisa ese número antes de emitir declaraciones posteriores.
En este caso, descubrí que usar una o dos reglas colocadas estratégicamente puede permitir ejecutar de manera preventiva las declaraciones ofensivas, lo que hace que Postgres devuelva la cantidad correcta de filas afectadas.