我通过向INSERT
语句添加字段,根据某些条件(例如操作类型或存在某个值)构建查询。但是我必须为具有不同参数列表的不同DBI execute
分支,如下所示:
if ($x) {$extraFields .= ' , X'; $extraValues= ',? '}
if ($y) {$extraFields .= ' , Y, Z'; $extraValues= ',?, ? '}
my $theBasicQuery = "INSERT INTO sometable (A, B, $extraFields) VALUES (?, ? $extraValues)";
$sth = $dbh->prepare($theBasicQuery) or error
# but I dont want to have to do this if for execute
if ($x) {$sth->execute(1,2,99);}
if ($y) {$sth->execute(1,2,88, 77);}
我更愿意这样做:
{$sth->execute($anArrayWithDifferentParams);}
这可能吗?或者还有其他方法可以做类似的事情吗?
答案 0 :(得分:6)
要更直接地回答这个问题,使用数组而不是标量列表执行查询的方法就是将数组传递给它。 $sth->execute(@params)
可以正常使用。
if ($x) {$extraFields .= ' , X'; $extraValues = ',? '; @params = (99); }
if ($y) {$extraFields .= ' , Y, Z'; $extraValues = ',?, ? '; @params = (88, 77); }
my $theBasicQuery = "INSERT INTO sometable (A, B, $extraFields) VALUES (?, ? $extraValues)";
$sth = $dbh->prepare($theBasicQuery) or error
$sth->execute(1,2, @params);
答案 1 :(得分:4)
我强烈建议您使用SQL构建工具来帮助您。我最喜欢的是SQL::Interp,与DBIx::Simple结合使用。这样的工具将为您管理绑定变量,DBIx :: Simple还会自动处理为您准备和重用语句句柄。 DBIx :: Simple / SQL :: Interp的解决方案如下所示:
$db->iquery("INSERT INTO sometable", {
a => 1,
b => 2,
%extra
});
SQL :: Abstract也很流行,并且具有类似语法的解决方案。
答案 2 :(得分:2)
一种方法:
my %insert = ( A => 1, B=> 2 );
if ($condition_x) {
$insert{X} = 99;
}
if ($condition_y) {
$insert{Y} = 88;
$insert{Z} = 77;
}
# 1. sprintf isn't very perlish, but I find it clearer here
# 2. quote_identifier(): you won't ever need this until you need it very badly
#
my $query = sprintf('INSERT INTO tbl (%s) VALUES (%s)',
join ', ' => map { $dbh->quote_identifier($_) } keys %insert,
join ', ' => ('?') x keys %insert);
my $sth = $dbh->prepare($query); # Perhaps prepare_cached, instead?
$sth->execute(values %insert);
警告:!DIY
如果可能的话,不要自己动手!按照其他地方的建议使用模块。其他人已经解决了这个问题,比上面更加有力和可靠。
答案 3 :(得分:0)
您可能会发现我的DBIx::PreQL库对此类任务很有帮助。它提供了一种标记SQL查询以便根据可用数据进行处理的方法。
DBIx :: PreQL使用简单的前缀和命名占位符来标记应包含查询的哪些行。
例如,*
表示“始终包含”,&
表示'包含该行的所有数据字段。
您的查询将标记如下:
* INSERT INTO sometable (
* A
* ,B
& ,C !C!
& ,D !D!
)
*VALUES (
* ?A?
* ,?B?
& ,?C?
& ,?D?
* )
然后您将查询和{ A => '123', B => 'foo', D => 'bar' }
之类的数据哈希传递给查询处理器,该查询处理器将返回查询:
INSERT INTO sometable (
A
,B
,D
)
VALUES (
?
,?
,?
)
参数列表(123, 'foo', 'bar')
。