(Nota:. Actualizado con la respuesta adoptada más adelante)PostgreSQL: ACTUALIZACIÓN implica movimiento a través de particiones
Para una PostgreSQL 8.1 (o posterior) tabla con particiones, ¿cómo se define un UPDATE
gatillo y el procedimiento para "mover" un registro de una partición a la otra, si el UPDATE
implica un cambio en el campo restringido que define la segregación de la partición?
Por ejemplo, tengo una tabla con particiones registros en los registros activos e inactivos, así:
create table RECORDS (RECORD varchar(64) not null, ACTIVE boolean default true);
create table ACTIVE_RECORDS (check (ACTIVE)) inherits RECORDS;
create table INACTIVE_RECORDS (check (not ACTIVE)) inherits RECORDS;
Los INSERT
de activación y función de trabajo así: nuevos registros activos llegar a poner en una mesa, y los nuevos registros inactivos en otro. Me gustaría UPDATE
s al campo ACTIVO para "mover" un registro de una tabla descendiente a la otra, pero estoy encontrando un error que sugiere que esto puede no ser posible.
gatillo mensaje:
pg=> CREATE OR REPLACE FUNCTION record_update()
RETURNS TRIGGER AS $$
BEGIN
IF (NEW.active = OLD.active) THEN
RETURN NEW;
ELSIF (NEW.active) THEN
INSERT INTO active_records VALUES (NEW.*);
DELETE FROM inactive_records WHERE record = NEW.record;
ELSE
INSERT INTO inactive_records VALUES (NEW.*);
DELETE FROM active_records WHERE record = NEW.record;
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
pg=> CREATE TRIGGER record_update_trigger
BEFORE UPDATE ON records
FOR EACH ROW EXECUTE PROCEDURE record_update();
pg=> select * from RECORDS;
record | active
--------+--------
foo | t -- 'foo' record actually in table ACTIVE_RECORDS
bar | f -- 'bar' record actually in table INACTIVE_RECORDS
(2 rows)
pg=> update RECORDS set ACTIVE = false where RECORD = 'foo';
ERROR: new row for relation "active_records" violates check constraint "active_records_active_check"
Jugando con el procedimiento de disparo (volviendo NULL y así sucesivamente) me sugiere que la restricción está marcada, y elevó el error, antes de invocar mi gatillo, lo que significa que mi enfoque actual no funcionará ¿Esto se puede poner a trabajar?
ACTUALIZACIÓN/RESPUESTA
A continuación se muestra el procedimiento UPDATE
gatillo Terminé usando el mismo procedimiento asignado a cada una de las particiones. Crédito es enteramente a Bell, cuya respuesta me dio la idea clave para disparar sobre las particiones:
CREATE OR REPLACE FUNCTION record_update()
RETURNS TRIGGER AS $$
BEGIN
IF ((TG_TABLE_NAME = 'active_records' AND NOT NEW.active)
OR
(TG_TABLE_NAME = 'inactive_records' AND NEW.active)) THEN
DELETE FROM records WHERE record = NEW.record;
INSERT INTO records VALUES (NEW.*);
RETURN NULL;
END IF;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
su "ejemplo" es incompleta: definición de "falta partitioned_records"; usted define un disparador para "particion_records" pero selecciona y actualiza "RECORDS". –
@Milen, gracias - errores de corte de dientes pasados. Remediaré – pilcrow
¿De qué sirve usar una partición en este contexto cuando podría usar un índice parcial? – kalu