2010-09-14 8 views
6

Normalerweise verwende ich einfache Anführungszeichen, aber irgendwann bekomme ich sehr lange Linien, die ich nicht brechen kann und muss auch Escape-Zeichen verwenden, so dass ich etwas wie folgt aus:Wie kann ich eine lange Zeichenfolge in Perl angeben?

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

ich weiß, gibt es verschiedene andere Möglichkeiten, zum Darstellen von Strings in Perl. Was würden Sie empfehlen?

UPDATE Vielen Dank für die SQL-Vorschläge. Ich lerne einige wertvolle Dinge, aber meine Frage bleibt (als eine allgemeine, unabhängig von SQL): Gibt es einen Operator, der das Zitieren ohne Zeilenumbrüche erlaubt?

, was ich jetzt tun ist so etwas wie:

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

die ziemlich hässlich.

+0

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

+0

* hust * Injektions-Sicherheitslücke * hust * http://xkcd.com/327/ – Ether

Antwort

3

Nein. Alle String-Erstellungsmethoden von Perl 5 kennen und enthalten Zeilenumbrüche. Sie können entweder den Verkettungsoperator verwenden, wie Sie in Ihrer Frage haben, oder abstrakte der Code weg erforderlich, um das Problem zu beheben:

#!/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

In diesem speziellen Fall würde ich empfehlen, Platzhalter verwenden, wenn Sie absolut 100% sicher sind, dass $ query_id nie „lustige Zeichen“

Obligatory xkcd reference

+0

Würden Sie gerne Platzhalter behandeln? –

+2

@David B Und selbst wenn Sie glauben, dass Sie sich so sicher sind, sollten Sie trotzdem Platzhalter verwenden. Siehe [Was sind Platzhalter in DBI, und warum sollte ich sie verwenden?] (Http://www.perlmonks.org/?node_id=7548) –

+1

Ausarbeitung auf http://bobby-tables.com/ – daxim

2

Im Beispiel enthalten kann, die Sie gegeben haben, Es gibt keinen Grund, die Zeile nicht zu durchbrechen, und die einfachen Anführungszeichen müssen nicht entfernt werden.

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

Aber, wie andere haben darauf hingewiesen, für Substitutionen in SQL-Abfragen, die Sie sind viel besser mit Platzhalter DBI weitergegeben werden werden.

+2

Sie sollten gib kein gefährlich falsches Beispiel. Zeigen Sie ihm von Anfang an, wie Sie es mit Platzhaltern richtig machen, oder Sie können sicher sein, dass jemand es kopiert/einfügt, dass es "funktioniert" und zufrieden ist. –

3

Als seine SQL Sie zitieren dann überlegen, etwas wie SQL::Abstract zu verwenden, um Ihre Abfrage zu erstellen.

Zum Beispiel:

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

Dies ist, was Sie in $query sehen würde:

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

und in @bind:

xyzzy 

So $query wurde bereits gebaut SQL akzeptieren Platzhalter und @bind h als die notwendigen Werte. So ist es dann nur übliche DBI Sachen wie diese die Abfrage auszuführen:

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

Jetzt haben Sie die alle Sicherheits- und Optimierung, die Platzhalter SQL bereitstellen (siehe SQL injection Wikipedia entry)

Auch diese vorherige Frage SO sehen: Is there SQL parameter binding for arrays?

/I3az/

10

Ich mag hier Dokumente, obwohl einige Leute sie verachten, weil der Terminator am Anfang der Zeile trotz Ihrer Einzugsebene erscheinen hat.

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

Ich mag auch meine SQL formatieren, damit ich die Struktur in der Aussage leicht sehen kann.

2

Für allgemeine Text Gebäude (re: Ihr Update) eine exotische Antwort zu bedienen eine Vorlagen-Engine Es ist ein bisschen wie ein printf auf Steroiden!

Hier ist ein Beispiel unter Verwendung von 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", 
}; 

Sie können auch es so bauen:

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

Und hier ist ein Beispiel mit einigen zitiert, etc:

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

Ein besseres Beispiel ist ungefähr so ​​mit Ihrem ursprünglichen SQL-Text:

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 = ?)', 
}; 

Siehe auch:


Und schließlich geht aus Exotisch bis komisch könnte man sogar ein neue quote-like operator mit 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 danke draegtun! –

+0

Sie sind herzlich willkommen.Und ich danke Ihnen dafür, dass Sie mich inspiriert haben, zwei (oder drei) Antworten zu schreiben! (besonders, dass ich meine PerlX :: QuoteOperator Trompete :) – draegtun

0

Zwar gibt es keine in Betreiber, dies zu tun gebaut ist, hier ist ein weiterer Ansatz, die funktionieren könnte:

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

Oder in zweistufigen Form :

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

Beide sind hässlich, aber funktional.