Обновите несколько столбцов в триггерной функции в plpgsql
Дана следующая схема:
create table account_type_a (
id SERIAL UNIQUE PRIMARY KEY,
some_column VARCHAR
);
create table account_type_b (
id SERIAL UNIQUE PRIMARY KEY,
some_other_column VARCHAR
);
create view account_type_a view AS select * from account_type_a;
create view account_type_b view AS select * from account_type_b;
Я пытаюсь создатьобщий Триггерная функция в plpgsql, которая позволяет обновлять представление:
create trigger trUpdate instead of UPDATE on account_view_type_a
for each row execute procedure updateAccount();
create trigger trUpdate instead of UPDATE on account_view_type_a
for each row execute procedure updateAccount();
Моим неудачным усилием было:
create function updateAccount() returns trigger as $
declare
target_table varchar := substring(TG_TABLE_NAME from '(.+)_view');
cols varchar;
begin
execute 'select string_agg(column_name,$1) from information_schema.columns
where table_name = $2' using ',', target_table into cols;
execute 'update ' || target_table || ' set (' || cols || ') = select ($1).*
where id = ($1).id' using NEW;
return NULL;
end;
$ language plpgsql;
Проблема заключается вupdate
заявление. Я не могу придумать синтаксис, который бы работал здесь. Я успешно реализовал это в PL / Perl, но был бы заинтересован в решении только для plpgsql.
Есть идеи?
Обновить
Как предложил @Erwin Brandstetter, вот код моего решения PL / Perl. Я поддержал некоторые из его предложений.
create function f_tr_up() returns trigger as $
use strict;
use warnings;
my $target_table = quote_ident($_TD->{'table_name'}) =~ s/^([\w]+)_view$/$1/r;
my $NEW = $_TD->{'new'};
my $cols = join(',', map { quote_ident($_) } keys $NEW);
my $vals = join(',', map { quote_literal($_) } values $NEW);
my $query = sprintf(
"update %s set (%s) = (%s) where id = %d",
$target_table,
$cols,
$vals,
$NEW->{'id'});
spi_exec_query($query);
return;
$ language plperl;