sql >> Base de Datos >  >> RDS >> PostgreSQL

postgres. límite de profundidad de pila plpgsql excedido

De acuerdo, si realmente desea activar el activador en la actualización, lo que podría hacer es establecer este activador como columna específica, de modo que no se active en una actualización de all_books , que está causando su recursividad. Algo como esto -

create trigger total2
after update of copy_id
on totalbooks
for each row
execute procedure total1();

Por supuesto, puede cambiar qué columnas activan la función, solo elegí copy_id porque eso es lo que estás contando.

SIN EMBARGO

Si está actualizando con un count() resultado, puede poner el gatillo en INSERT y DELETE comportamiento. De esta forma, el activador se activará cuando cambie el recuento, pero no se activará por la actualización. // EDITAR:Desde su sum es solo un recuento de todos los registros en copies , solo cambiará cuando se inserte o actualice un registro, por lo que ejecutar este disparador en la actualización no tendría sentido de todos modos.

EDITAR:pensé que sería útil agregar un enlace a CREAR Documentación de TRIGGER . Vea la sección etiquetada como "evento", porque esto detalla cómo especificar columnas en el evento.

EDITAR PARA NUEVA INFORMACIÓN:

Dado lo que parece que necesita lograr, creo que necesita repensar su diseño de datos, le sugiero que use una relación padre-hijo (cada vez que almacene en caché datos compartidos en muchas filas en una tabla porque comparten algo en común, eso es una señal de que es posible que necesite una tabla principal en su lugar).

Tener un books tabla donde cada fila es información sobre un libro (título, autor, etc.), y luego tiene una copies tabla donde cada fila contiene información sobre una copia de un libro (número de serie, última salida, etc.).

De esa manera, obtener el recuento de copias es tan simple como SELECT COUNT(*) FROM copies WHERE book_id=[some book id] .

Si realmente desea almacenar en caché el recuento en algún lugar, hágalo en los books mesa.

Crear un INSERT OR UPDATE desencadenar en copies eso hace UPDATE books SET copy_count=(SELECT COUNT(*) FROM copies WHERE book_id=NEW.book_id) WHERE id=NEW.book_id .

Luego crea un DELETE desencadenar en copias que UPDATE books SET copy_count=(SELECT COUNT(*) FROM copies WHERE book_id=OLD.book_id) WHERE id=OLD.book_id

El motivo de dos disparadores es que NEW variable solo está disponible en INSERT o UPDATE activadores y OLD solo está disponible en DELETE disparadores Podrías hacerlo todo como un disparador, pero eso requiere más código del que quería poner aquí.

Asegúrate de que todos tus activadores sean AFTER desencadenantes, o de lo contrario, una fila recién insertada/eliminada no se considerará en el conteo.