我通常使用简单的引号,但有时我得到很长的行,我无法破解,也需要使用转义字符,所以我得到这样的东西:
my $str = "select query_accession,query_tag,hit_accession,hit_tag,significance from summaryTables where query_id = \'$query_id\';"
我知道在Perl中表示字符串还有其他各种方法。你会推荐什么?
更新 感谢所有人提供与SQL相关的建议。我学到了一些有价值的东西,但是,我的问题仍然存在(作为一般问题,无论SQL如何):是否有一些操作符允许引用而不会捕获换行符?
我现在做的是:
my $str = "123 123 456 sdndfnd sdfdmd " .
"dfsdjkfs 343489 dfjsdj 3 34kdfsk kd " .
"fd kd9534 rfg 546 5";
非常难看。
答案 0 :(得分:10)
我喜欢这里的文件,虽然有些人鄙视他们,因为终结者必须出现在行的开头,尽管你的缩进级别。
my $str = <<"SQL";
SELECT
query_accession,
query_tag,
hit_accession,
hit_tag,
significance
FROM
summaryTables
WHERE
query_id = ?
SQL
我也喜欢格式化我的SQL,所以我可以很容易地看到语句中的结构。
答案 1 :(得分:5)
查看perlop's Quote-Like Operators。使用qq
表示双引号,q
表示单引号。
答案 2 :(得分:3)
正如您引用的SQL那样,请考虑使用类似SQL::Abstract
的内容来构建查询。
例如:
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 },
);
这是您在$query
中看到的内容:
SELECT query_accession, query_tag, hit_accession, hit_tag, significance FROM summaryTables WHERE ( query_id = ? )
和@bind
:
xyzzy
因此$query
已构建为接受SQL占位符,@bind
具有必要的值。所以它只是通常的DBI
这样的东西来运行查询:
my $sth = $dbh->prepare( $query );
$sth->execute( @bind );
现在,您拥有SQL占位符提供的所有安全性和优化(请参阅SQL injection Wikipedia entry)
另见以前的SO问题:Is there SQL parameter binding for arrays?
/ I3az /
答案 3 :(得分:3)
没有。所有Perl 5的字符串创建方法都知道并包含换行符。您可以像在问题中一样使用连接运算符,也可以抽象出解决问题所需的代码:
#!/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";
答案 4 :(得分:2)
在您给出的示例中,没有理由不破坏该行,也不需要转义单引号。
my $str = "select query_accession,
query_tag,
hit_accession,
hit_tag,significance
from summaryTables
where query_id = '$query_id';"
但是,正如其他人所指出的那样,对于将要传递给DBI的SQL查询中的替换,你最好使用占位符。
答案 5 :(得分:2)
对于一般文本构建( re:您的更新),一个奇特的答案是使用模板引擎。它有点像类固醇的printf!
以下是使用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",
};
您也可以像这样构建它:
my $str2 = buildtt '{all.join(" ")}' => {
all => [ "123 123 456 sdndfnd sdfdmd",
"dfsdjkfs 343489 dfjsdj 3 34kdfsk kd",
"fd kd9534 rfg 546 5" ],
};
以下是一些引用等的例子:
my $str3 = buildtt '{all.join(" ")}' => {
all => [ "no quoted text here",
"here's some and here's some more",
q{$str2 was "buildtt"},
$str2 ],
};
更好的例子就是这样的原始SQL文本:
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 = ? )',
};
另见:
String:TT
CPAN模块
最后,从异国情调到奇怪,你甚至可以用quote-like operator创建一个新的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 /
答案 6 :(得分:1)
在这种特殊情况下,我建议使用占位符,除非你绝对100%确定$ query_id永远不能包含“有趣的字符”
答案 7 :(得分:0)
虽然没有内置运算符来执行此操作,但这是另一种可行的方法:
(my $str = qq(
123 123 456 sdndfnd sdfdmd
dfsdjkfs 343489 dfjsdj 3 34kdfsk kd
fd kd9534 rfg 546 5
)) =~ s/\n//g;
或以两步形式:
my $str = qq(
123 123 456 sdndfnd sdfdmd
dfsdjkfs 343489 dfjsdj 3 34kdfsk kd
fd kd9534 rfg 546 5
);
$str =~ s/\n//g;
两者都很难看,但功能齐全。