Pregunta

He estado tratando de acelerar un disparador de auditoría genérico que había escrito en PL/PGSQL hace algún tiempo. En la actualización, genera una lista de columnas en la tabla que se actualiza e inserta filas en la tabla de auditoría registrando cualquier cambio (por tabla, columna, datos antes, datos después, etc.). La misma función de activación se usa en varias tablas.

Estoy jugando con PL/Perl, ya que parece ser mucho más rápido para la tarea en cuestión, pero parece que me he encontrado con un problema para diferenciar entre el valor nulo y vacío ('') en la base de datos.

En mi opinión, si una columna va de nula a una cadena vacía (o viceversa), ese es un cambio que necesito grabar. Sin embargo, utilizando las referencias de columnas nuevas/antiguas disponibles ($ _td-> {new/vieja} {$ columnName}), parece que no puedo diferenciar entre columnas que en realidad son nulas y las que contienen la cadena vacía. Las columnas que sé que son nulas están siendo atrapadas por las verificaciones vacías y de Undef, al igual que las columnas que sé que están vacías.

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

Sospecho que estoy haciendo algo tonto aquí, pero tal vez estoy tratando de hacer algo que simplemente no puedo hacer. ¿Algún consejo?

Editar - Uso de Postgres 8.4.4 para lo que vale

Editar: después de mirar la publicación de Filiprem a continuación (y muchas más pruebas), terminé con esto, que parece estar funcionando:

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

Atrapa la diferencia entre cadenas vacías y nulos y los registra todos apropiadamente en la tabla de auditoría.

¿Fue útil?

Solución

No especificó la versión PostgreSQL. El 9.0.5 he observado el mismo comportamiento (no estoy seguro de si es un error, vea los comentarios a continuación).

Esto es fácil de solucionar: primero puede probar la definición para atrapar nulas, y si pasa, pruebe la cadena vacía.

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" );
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a dba.stackexchange
scroll top