Aktualisieren Sie mehrere Spalten in einer Triggerfunktion in plpgsql
Angesichts des folgenden Schemas:
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;
Ich versuche einegenerisch Triggerfunktion in plpgsql, mit der die Ansicht aktualisiert werden kann:
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();
Eine erfolglose Anstrengung von mir war:
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;
Das Problem ist dasupdate
Aussage. Ich kann mir keine Syntax einfallen lassen, die hier funktionieren würde. Ich habe dies erfolgreich in PL / Perl implementiert, wäre aber an einer reinen plpgsql-Lösung interessiert.
Irgendwelche Ideen?
Aktualisieren
Wie @Erwin Brandstetter vorgeschlagen hat, ist hier der Code für meine PL / Perl-Lösung. Ich habe einige seiner Vorschläge aufgenommen.
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;