Frage

Ich habe versucht, einen generischen Auditing -Auslöser zu beschleunigen, den ich vor einiger Zeit in PL/PGSQL geschrieben hatte. Bei der Aktualisierung generiert es eine Liste von Spalten in der zu aktualisierten Tabelle und fügt Zeilen in die Prüfungstabelle ein, in der Änderungen aufgezeichnet werden (nach Tabelle, Spalte, Daten vor, Daten nach usw.). Die gleiche Triggerfunktion wird über mehrere Tabellen hinweg verwendet.

Ich spiele mit PL/Perl, da es für die jeweilige Aufgabe viel schneller zu sein scheint, aber ich scheine ein Problem bei der Differenzierung zwischen Null- und leerer Zeichenfolge ('') in der Datenbank zu sein.

In meinen Augen, wenn eine Spalte von Null zu einer leeren Zeichenfolge (oder umgekehrt) geht, ist dies eine Änderung, die ich aufnehmen muss. Mit den verfügbaren neuen/alten Spaltenreferenzen ($ _td-> {new/Old} {$ columnName}) kann ich jedoch nicht zwischen Spalten unterscheiden, die tatsächlich null sind, und solche, die die leere Zeichenfolge enthalten. Spalten, von denen ich weiß, dass sie Null sind, werden sowohl von den leeren als auch von den UNDEF -Überprüfungen gefangen, ebenso wie Spalten, von denen ich weiß, dass sie leer sind.

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

Ich vermute, dass ich hier etwas Dummes mache, aber vielleicht versuche ich etwas zu tun, was ich einfach nicht tun kann. Irgendein Rat?

Bearbeiten - Mit Postgres 8.4.4 für das, was es wert ist

Bearbeiten - Nachdem ich Filiprems Beitrag unten angesehen hatte (und viel mehr Tests), habe ich das gelandet, was zu funktionieren scheint:

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

Es fängt den Unterschied zwischen leeren Saiten und Nulls an und protokolliert sie alle angemessen in der Prüfungstisch.

War es hilfreich?

Lösung

Sie haben die PostgreSQL -Version nicht angegeben. Am 9.0.5 habe ich das gleiche Verhalten beobachtet (nicht sicher, ob es sich um einen Fehler handelt, siehe Kommentare unten).

Dies ist leicht zu verarbeiten.

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" );
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top