質問

しばらく前にPL/PGSQLで書いた一般的な監査トリガーをスピードアップしようとしています。更新では、更新されるテーブル内の列のリストを生成し、変更を記録する監査テーブルに行を挿入します(テーブル、列、データの前、データ後など)。同じトリガー関数が複数のテーブルで使用されます。

手元のタスクでははるかに高速であるように思われるPL/PERLをいじっていますが、データベースのnullと空の文字列( '')値を区別することに問題が発生したようです。

列がnullから空の文字列(またはその逆)に移動する場合、それは私が記録する必要がある変更です。ただし、利用可能な新しい/古い列参照($ _td-> {new/old} {$ columnname})を使用して、実際にnullの列と空の文字列を含む列を区別することはできないようです。私が知っている列は、空のチェックとUNDEFチェックの両方に捕まり、空の列と同様に、nullが捕らえられています。

    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");
    }

私はここで愚かなことをしているのではないかと疑っていますが、多分私は単にできないことをしようとしています。何かアドバイス?

編集 - それが価値があるものにpostgres8.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
        }
    }

空の文字列とヌルの違いをキャッチし、それらをすべて監査テーブルに適切にログに記録します。

役に立ちましたか?

解決

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