Domanda

Ho cercato di accelerare un trigger di controllo generico che avevo scritto in PL / pgSQL qualche tempo fa. Aggiornata, genera un elenco di colonne inserti righe registrazione delle eventuali modifiche (da tavolo, colonna, dati prima, dati dopo, etc) la tabella di revisione tavolo aggiornato e. La stessa funzione trigger viene utilizzato in più tabelle.

Sono giocare con pl / perl come sembra essere molto più veloce per il compito a portata di mano, ma mi sembra di aver incontrato un problema sulla differenziazione tra NULL e stringa vuota ( '') valore nel database.

Nella mia mente, se una colonna va da NULL a una stringa vuota (o viceversa), che è un cambiamento che ho bisogno di registrazione. Tuttavia, utilizzando i riferimenti di colonna nuova / vecchia disponibili ($ _TD -> {nuova / vecchia} {$ columnName}), posso non sembrano distinguere tra le colonne che sono in realtà nulla e quelli che contengono la stringa vuota. Colonne che so sono nulli vengono catturati da entrambe le verifiche undef vuoti e, come lo sono le colonne che so essere vuota.

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

Ho il sospetto che sto facendo qualcosa di stupido qui, ma forse sto cercando di fare qualcosa che io semplicemente non posso fare. Qualche consiglio?

Modifica - Utilizzo di Postgres 8.4.4 per quello che vale

Modifica - Dopo aver guardato il post di filiprem qui sotto (e molto altro ancora Testing), ho finito con questo, che sembra funzionare:

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

Si coglie la differenza tra stringhe vuote e NULL e li registra tutto in modo appropriato nella tabella di controllo.

È stato utile?

Soluzione

You did not specify PostgreSQL version. On 9.0.5 I have observed the same behavior (not sure if it's a bug, see comments below).

This is easy to workaround - you can first test for definedness to catch NULL, and if it passed, test for empty string.

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" );
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top