我继承了代码中包含非常大的SQL查询的代码,通常在heredocs中,并且内插的变量会动态选择一个或多个表,如下所示:
my $query = <<"SQL";
SELECT foo
FROM $some_table
WHERE bar = 'baz'
SQL
一些SQL查询非常大。问题是这使得我的Perl文件不必要地长而且难以阅读。代码分析和突出显示工具也无法解析heredoc SQL。
我想将SQL保存在实际的SQL文件中并更改上面的Perl代码以从本地目录中读取文件:
my $query = eval(get_sql('some-file.sql'));
... eval
- 这样可以扩展所有范围内的变量。
其中一些将发生在用户传递参数的Web可访问脚本中。绝对所有变量都被清理了,我在所有条件子句中使用了参数化语句(WHERE,AND等)
关于使用eval()
有很多FUD,所以我想知道:我的解决方案在Web应用程序中使用是否安全?
修改 ...
我应该进一步提到get_sql()
函数可能看起来像这样:
sub get_sql {
my ($filename) = @_;
my $sql = slurp("/path/to/file/$filename.sql");
my $query = qq|return qq{| . $sql . qq|};|;
return $query;
}
我知道引号运算符不能出现在将返回的SQL字符串中。
EDIT2 ...
给定任意数量的用例和/或约束,这是一个非常合理的问题。 Downvotes ......没有理由,伙计们。
答案 0 :(得分:2)
首先,
my $query = <<"SQL";
SELECT foo
FROM $some_table
WHERE bar = 'baz'
SQL
患有注射虫。它应该是
my $some_table_lit = $dbh->quote_identifier($some_table);
my $query = <<"SQL";
SELECT foo
FROM $some_table_lit
WHERE bar = 'baz'
SQL
您的模板系统非常糟糕。这相当于锤击螺钉的CS。它使编写不安全的代码变得非常容易(正如您已经完成的那样),它引入了高耦合,并使代码非常脆弱。
您应该使用比您当前使用的更好的模板系统(有或没有eval
)。
以下是使用Template-Toolkit的示例:
my $tt = Template->new();
$tt->process('some-file.sql', {
some_table => $dbh->quote_identifier($some_table),
})
or die $template->error();
SELECT foo
FROM [% some_table %]
WHERE bar = 'baz'