我一直在努力加快我在PL/PGSQL中写的通用审核触发器。在更新时,它生成了要更新表中的列列表,并在审核表中插入行记录任何更改(按表,列,数据,数据之后的数据等)。在多个表中使用相同的触发功能。

我正在使用PL/PERL玩耍,因为它似乎对手头的任务要快得多,但是我似乎在数据库中的空字符串和空字符串('')值之间遇到了问题。

在我的脑海中,如果一列从空字符串变为空字符串(反之亦然),这是我需要记录的更改。但是,使用可用的新/旧列引用($ _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");
    }

我怀疑我在这里做一些愚蠢的事情,但是也许我正在尝试做我根本做不到的事情。有建议吗?

编辑 - 使用Postgres 8.4.4的价值

编辑 - 在查看了下面的菲律宾帖子(以及更多测试)之后,我最终得到了这一点,这似乎正在起作用:

    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
        }
    }

它捕获了空字符串和nulls之间的区别,并在审核表中适当地记录了它们。

有帮助吗?

解决方案

您没有指定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" );
}
许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top