2010-09-14 12 views
6

que suelen utilizar comillas simples, pero en algún momento me sale muy largas colas que no puedo romper y también necesitará utilizar caracteres de escape, por lo que obtener algo como esto:¿Cómo puedo citar una cadena larga en Perl?

my $str = "select query_accession,query_tag,hit_accession,hit_tag,significance from summaryTables where query_id = \'$query_id\';" 

Sé que hay varias otras maneras para representar cadenas en Perl. ¿Qué recomendarías?

ACTUALIZACIÓN Gracias a todos ustedes por las sugerencias relacionadas con SQL. Aprendo algunas cosas valiosas, pero, mi pregunta permanece (como una general, independientemente de SQL): ¿hay algún operador que permita cotizar sin atrapar saltos de línea?

lo que hago ahora es algo así como:

my $str = "123 123 456 sdndfnd sdfdmd " . 
"dfsdjkfs 343489 dfjsdj 3 34kdfsk kd " . 
"fd kd9534 rfg 546 5"; 

que es bastante fea.

+0

ver http://www.perlmonks.org/?node_id=401006 –

+0

* tos * Vulnerabilidad de inyección * tos * http://xkcd.com/327/ – Ether

Respuesta

3

No. Todos los métodos de creación de cadenas de Perl 5 conocen e incluyen nuevas líneas. También se puede usar el operador de concatenación como lo hizo en su pregunta, o abstraer el código necesario para solucionar el problema:

#!/usr/bin/perl 

use strict; 
use warnings; 

sub single_line { 
    my @strings = @_; 
    for (@strings) { 
     s/\s+/ /g; 
     s/^\s+|\s+$//g; 
    } 
    return wantarray ? @strings : $strings[0]; 
} 


my $sql = single_line " 
    select query_accession,query_tag,hit_accession,hit_tag,significance 
    from summaryTables 
    where query_id = ?; 
"; 

print "[$sql]\n"; 
1

En este caso particular, le recomiendo usar marcadores de posición, a menos que esté absolutamente seguro de que el 100% $ query_id nunca puede contener "caracteres extraños"

Obligatory xkcd reference

+0

¿te gustaría elaborar sobre los marcadores de posición? –

+2

@David B E incluso si crees que estás tan seguro, sigue usando marcadores de posición de todos modos. Ver [¿Qué son los marcadores de posición en DBI, y por qué querría usarlos?] (Http://www.perlmonks.org/?node_id=7548) –

+1

Elaboración en http://bobby-tables.com/ – daxim

2

En el ejemplo que ha dado, no hay ninguna razón para no romper la línea y no hay necesidad de escapar de las comillas simples.

my $str = "select query_accession, 
        query_tag, 
        hit_accession, 
        hit_tag,significance 
      from summaryTables 
      where query_id = '$query_id';" 

Pero, como otros han señalado, por sustituciones en las consultas SQL que van a ser pasados ​​a DBI usted es mucho mejor usar marcadores de posición.

+2

Debería no dar un ejemplo peligrosamente incorrecto. Muéstrele la forma correcta de hacerlo con marcadores de posición desde el principio, o puede estar seguro de que alguien va a copiarlo/pegarlo, ver que "funciona" y estar satisfecho. –

3

Como su SQL está citando, considere usar algo como SQL::Abstract para generar su consulta.

Por ejemplo:

use SQL::Abstract; 

my $sql = SQL::Abstract->new; 
my $query_id = 'xyzzy'; # arbitary value 

my ($query, @bind) = $sql->select( 
    'summaryTables', 
    [qw/ query_accession query_tag hit_accession hit_tag significance /], 
    { query_id => $query_id }, 
); 

Esto es lo que se vería en $query:

SELECT query_accession, query_tag, hit_accession, hit_tag, significance FROM summaryTables WHERE (query_id = ?) 

y en @bind:

xyzzy 

Así $query ya construido para aceptar SQL marcador de posición y @bind h como los valores necesarios. Por lo que su continuación, sólo habitual DBI cosas como esta para ejecutar la consulta:

my $sth = $dbh->prepare($query); 
$sth->execute(@bind); 

Ahora usted tiene toda la seguridad y optimización que SQL marcadores de posición proporcionan (véase SQL injection Wikipedia entry)

también ven esto anterior SO pregunta: Is there SQL parameter binding for arrays?

/I3az/

10

me gusta aquí documentos, aunque algunas personas los desprecian porque el terminador tiene que aparecer al principio de la línea a pesar de que su nivel de sangría.

my $str = <<"SQL"; 
    SELECT 
    query_accession, 
    query_tag, 
    hit_accession, 
    hit_tag, 
    significance 
    FROM 
    summaryTables 
    WHERE 
    query_id = ? 
SQL 

También me gusta formatear mi SQL para que pueda ver fácilmente la estructura en la declaración.

2

Para la construcción texto general (re: su actualización) una respuesta exótica es utilizar un motor de plantilla. Es un poco como printf en esteroides!

Aquí hay un ejemplo usando Template Toolkit:

sub buildtt { 
    use Template; 
    my $tt = Template->new(START_TAG => '{', END_TAG => '}'); 
    $tt->process(\$_[0], $_[1], \my $output); 
    return $output; 
} 

my $str = buildtt '{a} {b} {c}' => { 
    a => "123 123 456 sdndfnd sdfdmd", 
    b => "dfsdjkfs 343489 dfjsdj 3 34kdfsk kd", 
    c => "fd kd9534 rfg 546 5", 
}; 

También se puede construir de esta manera:

my $str2 = buildtt '{all.join(" ")}' => { 
    all => [ "123 123 456 sdndfnd sdfdmd", 
      "dfsdjkfs 343489 dfjsdj 3 34kdfsk kd", 
      "fd kd9534 rfg 546 5" ], 
}; 

Y aquí es un ejemplo con un poco de citar, etc:

my $str3 = buildtt '{all.join(" ")}' => { 
    all => [ "no quoted text here", 
      "here's some and here's some more", 
      q{$str2 was "buildtt"}, 
      $str2 ], 
}; 

Un mejor ejemplo es algo como esto con su texto SQL original:

my $sql = buildtt 'select {v.join(",")} from {t} where {q}' => { 
    v => [qw/ query_accession query_tag hit_accession hit_tag significance /], 
    t => 'summaryTables', 
    q => '(query_id = ?)', 
}; 

Véase también:


Y, finalmente, al pasar de exótico a raro, incluso podrías crear un nueva quote-like operator con PerlX::QuoteOperator:

use PerlX::QuoteOperator q_strip_newline => { 
    -emulate => 'q', 
    -with => sub ($) { 
     my $txt = shift; 
     $txt =~ s/\n//g; 
     $txt; 
    }, 
}; 

my $str = q_strip_newline{123 123 456 sdndfnd sdfdmd 
dfsdjkfs 343489 dfjsdj 3 34kdfsk kd 
fd kd9534 rfg 546 5}; 

/I3az/

+0

+1 gracias draegtun! –

+0

De nada.Y gracias a cambio de inspirarme a escribir dos (¡o son tres!) Respuestas. (especialmente para hacerme explotar mi PerlX :: QuoteOperator trompeta :) – draegtun

0

Si bien no hay construido en el operador para hacer esto, aquí hay otro enfoque que podría funcionar:

(my $str = qq(
123 123 456 sdndfnd sdfdmd 
dfsdjkfs 343489 dfjsdj 3 34kdfsk kd 
fd kd9534 rfg 546 5 
)) =~ s/\n//g; 

o en forma de dos pasos :

my $str = qq(
123 123 456 sdndfnd sdfdmd 
dfsdjkfs 343489 dfjsdj 3 34kdfsk kd 
fd kd9534 rfg 546 5 
); 
$str =~ s/\n//g; 

Ambos son feos pero funcionales.

Cuestiones relacionadas