2009-11-06 9 views
13

Estoy usando el módulo DBI de Perl. Preparo una declaración usando marcadores de posición, luego ejecuto la consulta.¿Cómo puedo imprimir la consulta SQL ejecutada después de que DBI de Perl rellene los marcadores de posición?

¿Es posible imprimir la consulta final que se ejecutó sin escaparse manualmente de los parámetros y soltarlos en los marcadores de posición?

Gracias

+1

posible duplicado de [¿Cómo puedo hacer que DBI registre todas las consultas, incluidos los parámetros?] (Http://stackoverflow.com/questions/19703521/how-can-i-make-dbi-log-all-queries-including- params) – Jake

+0

@Jake esta pregunta fue hecha 4 años antes de la otra pregunta, también esta pregunta tiene mejores respuestas, (en mi opinión). Es por eso que he marcado la otra pregunta como el duplicado y el candidato para el cierre. – aidan

Respuesta

16

Ver Tracing in DBI. Las siguientes obras utilizando DBD::SQLite pero produce una gran cantidad de la producción:

$dbh->trace($dbh->parse_trace_flags('SQL|1|test')); 

Salida:

<- prepare('SELECT ... FROM ... WHERE ... = ?')= DBI::st=HASH(0x21ee924) at booklet-excel.pl line 213

<- execute('Inhaler')= '0E0' at booklet-excel.pl line 215

, etc, etc

Usted podría plug your own filter in to the trace stream a sólo mantienen prepare s .

+1

Upvoted por enseñarme sobre trazas, a pesar de que no responde la pregunta (porque, como otros señalaron, es imposible). Y este comentario está aquí solo porque me siento culpable por haber votado a favor una respuesta que sé que no responde la pregunta. jajaja: $ – msb

10
No

en general, porque DBI no necesariamente produce dicha consulta. Si su base de datos admite declaraciones preparadas y marcadores de posición en su API, DBI los pasará y dejará que la base de datos haga el trabajo, que es una de las razones para usar declaraciones preparadas.

8

Puede hacer una impresión de depuración de una declaración preparada utilizando el atributo Statement. Se puede acceder a esto con un "identificador de estado de cuenta" o un "identificador de base de datos".

print $sth->{Statement} # with a statement handle 

print $dbh->{Statement} # with a database handle 
+1

Esto simplemente devuelve la cadena pasada al último 'prepare' o' do', por lo que los marcadores de posición no se completan como se solicitó el OP. – ThisSuitIsBlackNot

+1

Podría usar 'print Dumper ($ statement_handle -> {'ParamValues'});' para imprimir los parámetros de vinculación por separado: podría ser suficiente para depurar la mayoría de las consultas. – user1027562

1

Como dice masto en general, los marcadores de posición en el SQL no se reemplazan directamente con sus parámetros. El objetivo de SQL parametrizado es que el SQL con marcadores de posición se pase al motor de la base de datos para analizar una vez y luego solo recibe los parámetros.

Como notas idssl puede obtener el SQL de vuelta desde la instrucción o el identificador de conexión y también puede recuperar los parámetros desde ParamValues. Si no desea hacerlo usted mismo, puede usar algo como DBIx::Log4perl para registrar solo el SQL y los parámetros. Ver DBIX_L4P_LOG_DELAYBINDPARAM que da salida a algo como esto:

DEBUG - prepare(0.1): 'insert into mje values(?,?)' 
DEBUG - $execute(0.1) = [{':p1' => 1,':p2' => 'fred'},undef]; 

Por supuesto, ya que utiliza Log :: Log4perl se puede omitir el "Test -" si lo desea. Hay un pequeño tutorial para usar DBIx :: Log4perl here.

Debería poder usar DBIx :: Log4perl con cualquier DBD y si por algún motivo no puede RT y lo veré.

Si no quiere ir con DBIx :: Log4perl y las opciones de rastreo de DBI no se ajustan a sus necesidades, puede escribir devoluciones de llamada para los métodos de preparación/selección */ejecución de DBI y recopilar lo que quiera en ellos.

0

Si no desea crear su propio módulo de seguimiento (como lo sugiere Sinan), es mejor que intente imprimir el hash del argumento antes de pasarlo al $sth->execute(). Esto es especialmente cierto, ya que la funcionalidad "Trace" depende de DBMS y $sth->{Statement} solo devuelve la declaración de marcador de posición SQL. Esto es lo que hice.

... 
while (my $row = $csv->getline_hr($fh)) { 
    my $cval = ""; 
    my $tquery = $query; 
    foreach my $j (@cols) { 
      $cval = $row->{$j}; 
      $tquery =~ s/\?/\'$cval\'/; 
    } 
    print "$tquery\n\n"; 
    $rc = $sth->execute(@{$row}{@cols}); 
} 

Dónde he utilizado Texto :: CSV ... NOTA: Esto no es exacta, debido a un manejo depende de la implementación del DBMS { '} s.

1

Esto funciona para DBD::mysql con el lado del servidor se preparan con discapacidad (por defecto):

$ DBI_TRACE=2 perl your-script-here 

Se imprimirá cada declaración dos veces, una vez antes de parámetros de unión y una vez después. Este último será un SQL bien formado que puede ejecutar usted mismo.

Cuestiones relacionadas