Jaf*_*foy 5 postgresql trigger null perl
我一直在尝试加快我在 pl/pgsql 中编写的通用审计触发器的速度。更新时,它会生成正在更新的表中的列列表,并在审计表中插入记录任何更改的行(按表、列、之前的数据、之后的数据等)。跨多个表使用相同的触发器函数。
我正在尝试使用 pl/perl,因为它对于手头的任务似乎要快得多,但我似乎遇到了区分数据库中 NULL 和空字符串 ('') 值的问题。
在我看来,如果一列从 NULL 变为空字符串(反之亦然),这是我需要记录的更改。但是,使用可用的新/旧列引用 ($_TD->{new/old}{$columnName}),我似乎无法区分实际为空的列和包含空字符串的列。我知道为空的列正在被空和 undef 检查捕获,我知道的列也是空的。
if($_TD->{new}{$column} eq '') {
elog(NOTICE, "New value in column $column is empty");
}
if($_TD->{old}{$column} eq '') {
elog(NOTICE, "Old value in column $column is empty");
}
if($_TD->{new}{$column} eq undef) {
elog(NOTICE, "New value in column $column is not defined");
}
if($_TD->{old}{$column} eq undef) {
elog(NOTICE, "Old value in column $column is not defined");
}
Run Code Online (Sandbox Code Playgroud)
我怀疑我在这里做了一些愚蠢的事情,但也许我正在尝试做一些我根本无法做的事情。有什么建议吗?
编辑 - 使用 Postgres 8.4.4 的价值
编辑 - 在查看下面 filiprem 的帖子(以及更多测试)后,我最终得到了这个,这似乎有效:
my %newrow = %{$_TD->{new}};
my %oldrow = %{$_TD->{old}};
my $valChanged;
while (($column,$value) = each %newrow) {
$valChanged = 0;
if($newrow{$column} ne $oldrow{$column}) {
$valChanged = 1;
elog(NOTICE, "Values in column $column differ. New: $_TD->{new}{$column}, Old: $_TD->{old}{$column}");
}
elsif(!defined($newrow{$column}) && defined($oldrow{$column})) {
elog(NOTICE, "New row contains nulled out field");
$valChanged = 1;
}
elsif(defined($newrow{$column}) && !defined($oldrow{$column})) {
elog(NOTICE, "New row contains newly populated field");
$valChanged = 1;
}
if($valChanged) {
### Update audit table
}
}
Run Code Online (Sandbox Code Playgroud)
它捕捉空字符串和 NULL 之间的差异,并将它们全部适当地记录在审计表中。
您没有指定 PostgreSQL 版本。在 9.0.5 上我观察到了相同的行为(不确定这是否是一个错误,请参阅下面的评论)。
这很容易解决 - 您可以首先测试捕获 NULL 的定义,如果通过,则测试空字符串。
if ( not defined $_TD->{ new }{ $column } ) {
elog( NOTICE, "New value in column $column is not defined" );
}
elsif ( $_TD->{ new }{ $column } eq '' ) {
elog( NOTICE, "New value in column $column is empty" );
}
if ( not defined $_TD->{ old }{ $column } ) {
elog( NOTICE, "Old value in column $column is not defined" );
}
elsif ( $_TD->{ old }{ $column } eq '' ) {
elog( NOTICE, "Old value in column $column is empty" );
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1182 次 |
最近记录: |