[英]perl/dbi/sql stumped by “operation must use an updatable query” error
我有一个Perl脚本,该脚本建立了一个sql cmd来将MS Access数据库中某些表中的某些字段设置为NULL(对不起)。 这是一个简化的模型。
my $nonKeyFields_hashref = { "country" => "ZZZ",
"address3" => "FOO"
};
my $keyFields_hashref = { "address1" => "1212 O'Mally Street", # embedded single quote here is causing the problem
"client ID" => "1234567"
};
my $sqlCmd = "UPDATE myTable SET ";
$sqlCmd .= join( ", " , map{ "[?} = NULL "} keys $nonKeyFields_hashref;
$sqlCmd .= " WHERE ";
$sqlCmd .= join( " AND " , map{ "[?} = ? "} keys $keyFields_hashref;
# sqlCmd contains "UPDATE myTable SET [?] = NULL, [?} = NULL WHERE [?] = ? AND [?] = ?"
$sth = $dbh->prepare( $sqlCmd);
if( !defined( $sth)) {
_pushErrorMsg("sth failed to define - ".$DBI::errstr);
$errorHit = 1;
} else {
my @cmd_arry = ();
push( @cmd_arry, $_ ) for keys $nonKeyFields_hashref;
push( @cmd_arry, $_ , $keyFields_hashref->{$_} ) for keys $keyFields_hashref;
print Dumper( @cmd_arry);
# dumper shows @cmd_arry contains ("country", "address3", "address1", "1212 O'Mally Street", "client ID", "1234567")
# which is six elements, which jibes with the query's question-marks
$sth->execute( @cmd_arry); # errors here with the given message
....
}
当数据不包含讨厌的嵌入式单引号时,此代码非常有用。 我希望绑定可以解决这个问题,但是没有运气。
有人对这个单引号问题有解决方案吗?
提前致谢,
仍在学习的史蒂夫。
该代码包含语法错误,原因是a)缺少联接调用的close)b)缺少对Data :: Dumper的使用。 我假设您正在使用最新的Perl,因为您似乎期望$ hash_references被自动取消引用。
数据库引擎接受列名参数是不寻常的-这绝对不适用于大多数数据库。
就我所知,您在谈论的单引号对该脚本没有影响-它只是破坏了代码,而其他代码又为SQL语句增加了太多参数。 SQL语句需要4个列名,然后推4个列名和2个值。
我假设您是说“ push(@cmd_arry,$ _,$ keyFields_hashref-> {$ _}”)是“ push(@cmd_arry,$ _”。
一些轻微的重构就达到了目的:
$sqlCmd = "UPDATE [$tableName] SET ";
$sqlCmd .= join( ", ", map { "[$_] = NULL "} keys $nonKeyFields_hashref);
$sqlCmd .= " WHERE ";
$sqlCmd .= join( " AND ", map { "[$_] = ? "} keys $keyFields_hashref);
# sneaky values may contain embedded single-quotes for GoGo's , 4343 Little's Court, etc
my $sth = undef;
$sth = $dbh->prepare( $sqlCmd);
if( !defined( $sth)) {
_pushErrorMsg("sth failed to define - ".$DBI::errstr);
$errorHit = 1;
} else {
my @cmd_arry = ();
push( @cmd_arry, $keyFields_hashref->{$_} ) for keys( $keyFields_hashref);
print Dumper( @cmd_arry);
my $resultCnt = $sth->execute( @cmd_arry);
if( my $errorMsg = $dbh->errstr )
....
感谢所有回应!
仍在学习的史蒂夫
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.