I have a central table in a library-like database called deployments_retrievals. This table stores all 'deployment' (e.g., checkouts) and 'retrieval' (e.g., returns) events. I next have a table of metadata_<gear>, containing metadata such as gear serial number. Finally, I have a third table containing deployment information for each specific gear type, deployment_<gear>, which stores information about each gear item before and after each deployment event. This third table is used to link each gear serial number to a deployment event id deployments_retrievals.deploy_id.
What I'd like to do is update metadata_<gear>.current_location whenever deployments_retrievals is updated. I can successfully update the gear table when one condition is met; however, I'm having trouble understanding the syntax for updating when multiple conditions are involved - essentially I'm having trouble combining postgresql UPDATE, IF/ELSEIF/ELSE, and a subquery. I'm looking for something along these lines:
create or replace function trigger_update_gearlocation()
returns trigger as
$body$
begin
-- If deployments_retrievals status is deployed (0), retrieved (1), or lost (2), then updated the <gear>_locations table with appropriate current_location.
update metadata_receivers
if DEPLOY_STATUS.retrieval_status = 0 then
set metadata_receivers.current_location = 'Deployed'
elseif DEPLOY_STATUS.retrieval_status = 1 then
set metadata_receivers.current_location = 'Retrieved'
elseif DEPLOY_STATUS.retrieval_status = 2 then
set metadata_receivers.current_location = 'Lost'
-- This selects all receiver serial numbers that are DEPLOYED, RETRIEVED, or LOST, + their last deploy time as "DEPLOY_STATUS".
from (
select deployment_receiver.receiver_sn as serial_number, deployments_retrievals.retrieval_status, deployments_retrievals.deploy_datetime
from deployment_receiver inner join deployments_retrievals
on deployment_receiver.deploy_id = deployments_retrievals.deploy_id
--where retrieval_status <> 1
) as DEPLOY_STATUS
where DEPLOY_STATUS.serial_number = metadata_receivers.receiver_sn;
end;
$body$
language plpgsql;
CREATE TRIGGER "deployLocations" AFTER update ON deployments_retrievals FOR EACH ROW EXECUTE
PROCEDURE trigger_update_gearlocation();
My three tables, for reproducibility:
-- 1. The table to be updated. Contains metadata on the gear, including current_location.
CREATE TABLE metadata_receivers
(
receiver_sn integer PRIMARY KEY,
current_location varchar (255), -- Trigger "trigger_update_gearlocation()" updates column if deployment status is 0, receiver status is "deployed"; 1 - "retrieved"; 2 - "lost"
date_retired date,
date_updated timestamp DEFAULT current_timestamp
);
-- 2. Deployments & retrievals table - stores all 'checkout' and 'return' events for all types of gear.
CREATE TABLE deployments_retrievals
(
deploy_id bigserial primary key,
deploy_datetime timestamptz NOT NULL,
retrieval_status integer check (retrieval_status in ('0', '1', '2')) NOT NULL DEFAULT '0',
retrieval_datetime timestamptz check (retrieval_datetime > deploy_datetime),
date_updated timestamp DEFAULT current_timestamp
);
-- 3. Deployment information specifically related to receivers only. Used to link the receiver metadata to individual deployment events.
CREATE TABLE deployment_receiver
(
receiverdeploy_id bigserial primary key,
receiver_sn integer REFERENCES metadata_receivers(receiver_sn) on update cascade on delete cascade not null,
deploy_id integer REFERENCES deployments_retrievals(deploy_id) on update cascade on delete cascade not null,
-- ... various misc fields
date_updated timestamp DEFAULT current_timestamp,
unique(receiver_sn, deploy_id)
);
Any notes on whether or not this is best practice or how to streamline would be appreciated.
Aucun commentaire:
Enregistrer un commentaire