2013-07-22 1 views
0

У меня есть скрипт Perl, который создает sql cmd для установки определенных полей в NULL в определенной таблице в MS Access db (извините). Вот упрощенный макет.perl/dbi/sql, в котором находится ошибка «операция должна использовать обновляемый запрос»

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 
    .... 
} 

этот код отлично работает, когда данные НЕ содержат неприятных встроенных одиночных кавычек. Я надеялся, что привязка решит эту проблему, но такой удачи не будет.

У кого-нибудь есть решение этой проблемы с одной кавычкой?

Спасибо заранее,

Тем не менее, обучение Стива.

ответ

0

Этот код содержит синтаксические ошибки из-за отсутствия) закрытия соединений) b) Отсутствие использования для Data :: Dumper. Я предполагаю, что вы используете недавний Perl, поскольку вы, кажется, ожидаете, что $ hash_references автоматически разыгрываются.

Необычно для механизма базы данных принимать параметры для имен столбцов - это определенно не будет работать с большинством баз данных.

Одиночная цитата, о которой вы говорите, не влияет на этот сценарий, насколько я могу видеть - он просто разбит на код в другом, нажимая слишком много параметров для инструкции SQL. Оператор SQL хочет 4 имени столбца и вы нажимаете 4 имени столбца и 2 значения.

Я полагаю, вы имели в виду "толчок (@cmd_arry, $ _, $ keyFields_hashref -> {$ _}", чтобы быть "толчок (@cmd_arry, $ _"

+0

даст это попробовать, спасибо за ваш ответ – user1201168

+0

я только что понял, ты такой же человек, который спросил Http:! // stackove rflow.com/questions/17479928/trouble-creating-table-with-a-field-of-type-memo-in-access-db-using-perl-dbi-odb и не отмечал моего ответа. Разве он не ответил на ваш вопрос? – bohica

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

спасибо всем, кто откликнулся

Еще обучения Стив

+0

Это то, что я сказал, и все же вы не отмечаете никаких моих ответов в качестве ответов. – bohica