Diego Schulz dijo [Thu, Apr 23, 2009 at 01:21:23PM -0400]:
> >> Me ahorro un solo problema importante (en mi caso):  cuando intentaba
> >> insertar blobs en su respectiva tabla tenia unos warnings como este,
> >>
> >>    WARNING:  uso no estandar de \\ en un literal de cadena
> >>    LINE 1: ...5253, '9c42d5b5ca53f123bfa2483d0dc0b2e09df493f0', 
> >> '\\177ELF\...
> >>                                                              ^
> >>    HINT:  Use '' para escribir comillas en cadenas, o use la sintaxis
> >> de escape de cadenas (E'\\').
> >
> > ¿Y probaste a usar E'\\177ELF\...' como lo señala el hint?
> >
> 
> Si, pero daba problemas usando parametros nombrados del tipo
> 
>    query.prepare("INSERT INTO archivo (nombre, rutaorig, descripcion,
> tam , hash , blob) "
>                           "VALUES ( :nombre, :rutaorig , :descripcion,
> :tam , :hash, E\'\\\\:blob'\' ) ");
> 
> y tambien usando parametros posicionales
> 
>    query.prepare("INSERT INTO archivo (nombre, rutaorig, descripcion,
> tam , hash , blob) "
>                           "VALUES ( ?,?,?,?,?, E'\\\\?' ");
> (...)

Lo más común cuando trabajas con bytea es encargarle al conector de BD
hacer la conversión. Por ejemplo, en Perl:

$sth = $dbd->prepare('INSERT INTO archivo ' .
                     '(nombre, rutaorig, descripcion, blob) ' .
                     'VALUES (?, ?, ?, ?));
$sth->bind_param(1, $nombre);
$sth->bind_param(2, $ruta);
$sth->bind_param(3, $descr);
$sth->bind_param(4, $blob, {pg_type=>DBD::Pg::PG_BYTEA});
$sth->execute;

Esto es, "desdoblamos" la solicitud especificando a cada uno de los
parámetros por separado. bind_param acepta opcionalmente el tercer
atributo, donde estamos indicando el tipo de datos a emplear (y es
DBD::Pg quien se encarga de codificarlo). Al recuperar los datos no
hace falta escapar nada.

En Ruby hago algo similar (a través de ActiveRecord) el acceso es
completamente transparente - El framework se encarga de estas
minucias. 

Como sea, si quisieras codificar los datos para pasarlos a través de
una cadena armada como lo estabas especificando, te puede servir esta
función que alguna vez hice - aunque dista de ser perfecta
(especialmente en lo concerniente al rendimiento). Está escrita en
Perl, y recibe como único parámetro un filehandle a leer:

sub escape_octal {
    my ($fh, $out, $in);
    $fh = shift;

    while (my $in = <$fh>) {
    $out .= join('', map {
            my $ord = ord($_);
            ($ord >= 32 and $ord <= 126 and ord != 92) ? $_ :
                sprintf('\\%03o', $ord);
            } split (//, $in));
    }
    return $out;
}

-- 
Gunnar Wolf - [email protected] - (+52-55)5623-0154 / 1451-2244
PGP key 1024D/8BB527AF 2001-10-23
Fingerprint: 0C79 D2D1 2C4E 9CE4 5973  F800 D80E F35A 8BB5 27AF
--
TIP 4: No hagas 'kill -9' a postmaster

Responder a