0

MS Access データベースの特定のテーブルで特定のフィールドを NULL に設定する SQL コマンドを作成する Perl スクリプトがあります (申し訳ありません)。これが単純化されたモックアップです。

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

そのコードには、a) join 呼び出しでの終了の欠落、b) Data::Dumper の使用の欠落による構文エラーが含まれています。$hash_references が自動的に逆参照されることを期待しているように見えるので、最近の Perl を使用していると思います。

データベース エンジンが列名のパラメーターを受け入れるのは珍しいことです。これは、ほとんどのデータベースでは確実に機能しません。

あなたが話している一重引用符は、私が見る限り、このスクリプトに影響を与えません-elseのコードがSQLステートメントのパラメーターをプッシュしすぎているために壊れているだけです。SQL ステートメントは 4 つの列名を必要とし、4 つの列名と 2 つの値をプッシュします。

「push( @cmd_arry, $_ , $keyFields_hashref->{$_}」は「push( @cmd_arry, $_」という意味だったと思います。

于 2013-07-22T08:38:21.110 に答える
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 に答える