Триггер PostgreSQL UPDATE для SELECT с использованием операторов IF / ELSE - PullRequest
0 голосов
/ 17 сентября 2018

Я хотел бы обновить t1 всякий раз, когда t2 обновляется.Однако мне нужно использовать таблицу t3, чтобы присоединиться к ним, что означает, что мне нужен подзапрос.Я могу успешно обновить t1 при выполнении одного условия;Однако у меня возникают проблемы с пониманием синтаксиса для обновления, когда задействованы несколько условий - по существу, у меня возникают проблемы при объединении postgresql UPDATE, IF/ELSEIF/ELSE и подзапроса.Я ищу что-то вроде этого:

-- TABLES

create table t1
(
serial_number        integer primary key,
current_location     varchar
);

create table t2
(
some_id              bigserial primary key,
status               integer
);

create table t3
(
serial_number        integer REFERENCES t1(serial_number),
some_id              integer REFERENCES t2(some_id),
unique(serial_number, some_id)
);


-- TRIGGER

create or replace function trigger_update_currentlocation()
returns trigger as 
$body$
begin

-- If SUBQUERY status is deployed (0), retrieved (1), or lost (2), then update t1 with appropriate current_location. 

-- THIS IS WHAT FAILS - SQL does not recognize 'SUBQUERY.status' in each if/elseif statement.
update t1
    if SUBQUERY.status = 0 then
        set t1.current_location = 'Deployed'

    elseif SUBQUERY.status = 1 then
        set t1.current_location = 'Retrieved'

    elseif SUBQUERY.status = 2 then
        set t1.current_location = 'Lost'

-- This joins t3 and t2 in order to select only serial_numbers with a status. Column `some_id` does not exist in t1 and thus can't be used to join t1 to t3 directly. 
from (
    select t3.serial_number, t2.status
    from t2 inner join t3
        on t2.some_id = t3.some_id
    ) as SUBQUERY

-- This matches SUBQUERY serial number to t1 serial number, so that only the appropriate rows in t1 are updated.
where SUBQUERY.serial_number = t1.serial_number;

end;
$body$
language plpgsql;

CREATE TRIGGER "deployLocations" AFTER update ON t2 FOR EACH ROW EXECUTE 
PROCEDURE trigger_update_currentlocation();

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Этот запрос должен делать то, что вам нужно:

update t1 
  set current_location = 
    case t2.status
        when 0 then 'Deployed'
        when 1 then 'Retrieved'
        when 2 then 'Lost'
    end
from t2 inner join t3
   on t2.some_id = t3.some_id
where t3.serial_number = t1.serial_number;
0 голосов
/ 17 сентября 2018

Замените, если еще оператором case в обновлении, он позаботится о проблеме, с которой вы столкнулись.

update t1
        set t1.current_location =   CASE  
                                    WHEN SUBQUERY.status = 0 THEN 'Deployed' 
                                    WHEN SUBQUERY.status = 1 THEN 'Retrieved' 
                                    WHEN SUBQUERY.status = 2 THEN 'Lost' 
                                    ELSE t1.current_location
                                END 
from (
    select t3.serial_number, t2.status
    from t2 inner join t3
        on t2.some_id = t3.some_id
    ) as SUBQUERY

where SUBQUERY.serial_number = t1.serial_number;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...