0

我有一个 Perl 脚本,它构建了一个 sql cmd 以将 MS Access db 中某个表中的某些字段设置为 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
  ....
}

当数据不包含讨厌的嵌入式单引号时,此代码效果很好。我希望绑定能解决这个问题,但没有这样的运气。

有人有解决这个单引号问题的方法吗?

提前致谢,

仍在学习史蒂夫。

4

2 回答 2

0

一些轻微的重构就成功了:

$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 ) 
 ....

感谢所有回复的人!

仍在学习的史蒂夫

于 2013-07-22T17:17:27.663 回答
0

该代码包含语法错误,原因是 a) 连接调用中缺少关闭 ) b) 缺少对 Data::Dumper 的使用。我假设您使用的是最近的 Perl,因为您似乎期望 $hash_references 会自动取消引用。

数据库引擎接受列名参数是不寻常的——这绝对不适用于大多数数据库。

据我所知,您所说的单引号对这个脚本没有影响——它只是在 else 中为 SQL 语句推送了太多参数而被破坏了。SQL 语句需要 4 个列名,您推送 4 个列名和 2 个值。

我想你的意思是“push(@cmd_arry,$_,$keyFields_hashref->{$_}”是“push(@cmd_arry,$_”。

于 2013-07-22T08:38:21.110 回答