簡體   English   中英

perl / dbi / sql被“操作必須使用可更新的查詢”困擾

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM