简体   繁体   中英

Updating multiple columns in Postgresql

I have a table called Availability(uname, date, start_time, end_time) where a user can input the time slots that they are free. Now I want to create a trigger before inserting or updating on the Availability table to check if the new input overlaps with an existing availability made by the same user on the same date. If it overlaps, I want to merge both time slots. This is my code so far:

create or replace function check_overlap()
returns trigger as $$
begin
    update availability a0
    set (a0.start_time, a0.end_time) =
        case (select a.start_time, a.end_time from availability a where a.uname = new.uname and a.start_date = new.start_date)
            when NEW.start_time < a0.start_time and NEW.end_time < a0.end_time then row(NEW.start_time, a0.end_time)
            when NEW.start_time > a0.start_time and NEW.end_time > a0.end_time then row(a0.start_time, NEW.end_time)
            when NEW.start_time < a0.start_time and NEW.end_time > a0.end_time then row(NEW.start_time, NEW.end_time)
            when NEW.start_time > a0.start_time and NEW.end_time < a0.end_time then row(a0.start_time, a0.end_time)
        end;
end;
$$ language plpgsql;

create trigger tg_INSERT_UPDATE_avail
before insert or update
on availability
for each row
execute function check_overlap();

Now, the issue is that I am facing this error:

ERROR:  source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
LINE 3:   case (select a.s_time, a.e_time from availability a where ...
          ^

Any insights are appreciated!

You can probably simply move the SELECT outside of the CASE statement:

update availability a0 set (a0.start_time, a0.end_time) = (
    select case when NEW.start_time < a0.start_time and NEW.end_time < a0.end_time then row(NEW.start_time, a0.end_time)
        when NEW.start_time > a0.start_time and NEW.end_time > a0.end_time then row(a0.start_time, NEW.end_time)
        when NEW.start_time < a0.start_time and NEW.end_time > a0.end_time then row(NEW.start_time, NEW.end_time)
        when NEW.start_time > a0.start_time and NEW.end_time < a0.end_time then row(a0.start_time, a0.end_time)
        else row(NEW.start_time, NEW.end_time)
    end
    from availability a where a.uname = new.uname and a.start_date = new.start_date
);

BTW: I cannot test this but the update without a where clause looks strange to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM