我不知道“variadic”实际上是否是正确的词,但我在谈论可以采用值列表的事情,比如IN().如果您已经使用DBI很长时间,您可能尝试这样做:
(注意:为简洁起见,所有示例都非常简化)
my $vals = join ',',@numbers; my $sth = $dbh->prepare( "SELECT * FROM mytbl WHERE foo IN( ? )" ); $sth->execute( $vals ); # doesn't work
DBI占位符根本不支持这些类型的恶作剧,它们各自的价值是多少?或者根据我所知,什么也没有.
这导致我最终做了类似的事情:
my $sth = $dbh->prepare( "SELECT * FROM mytbl WHERE foo IN ( $vals )" );
这不是那么可怕,但考虑一个函数,就像我今天写的一样,必须接受一些带有IN子句和值列表的任意sql
sub example { my $self = shift; my ( $sql,@args ) = @_; my $vals = join ',@args; $sql =~ s/XXX/$vals/; <---- # AARRRGHGH my $sth = $self->dbh->prepare( $sql ); ... }
这最终会被看起来像的东西调用
my $sql = "SELECT * FROM mytbl WHERE foo IN( XXX ) AND bar = 42 ORDER BY baz"; my $result = $self->example( $sql,@quux );
这真的冒犯了我的审美感.以编程方式构建自定义sql是一个非常大的痛苦;如果我不需要,我不想走下去修复我的sql字符串的道路.
有没有更好的办法?
解决方法
sprintf在这种情况下很方便:
my $sth = $dbh->prepare( sprintf( 'SELECT * FROM mytbl WHERE foo IN( %s )',join(',('?') x @numbers) ) );