2

我正在编写一个 perl 脚本来使用 mysql 数据库中的数据更新 oracle 数据库中的表。

我是 perl 的新手,所以任何帮助将不胜感激。

我目前有以下内容,它不会更新 oracle 数据库,但也不会引发任何错误。

数据库都已初始化。

我希望 oracle tblrecommendations 表使用 mysql tblrecommendations 表中的内容更新性能。

提前致谢。

#transfer data
sub do_crc_company_performance {

my ($sth_mysql, $sth_oracle);
my $sql_details = <<END_SQL;
select
  tblRecommendations.code,
  tblRecommendations.performance
from 
  crc.tblRecommendations
where
  length(tblRecommendations.code) = '3'
END_SQL

# variables to bind values to

my ($code, $performance);

eval {
    # prepare our select statement for mysql
    $sth_mysql = $dbh_mysql->prepare($sql_details);
    $sth_mysql->execute;
    $sth_mysql->bind_columns(\($code, $performance));
    # create oracle insertion query
    $sth_oracle = $dbh_oracle->prepare(q{UPDATE TBLRECOMMENDATIONS
                                        SET PERFORMANCE = '$performance'
                                        WHERE CODE = '$code'});
    while ( $sth_mysql->fetch ) {
        $performance = Encode::decode_utf8($performance); # set the flag
        # feed the data into the tblRecommendations table
        $sth_oracle->execute();
    }
};

if ($@) {
    # what went wrong
    push (@errors, "Unable to update company details: $@");
    # rollback our transaction
    $dbh_oracle->rollback()
} 
$sth_oracle->finish if ($sth_oracle);
$sth_mysql->finish if ($sth_mysql);
}
4

3 回答 3

3

您的问题是您的q{}quoting,这是没有插值的文字字符串引用。因此,您正在搜索code字段设置为五个字符的字符串 value的记录$code

一种解决方案是使用插值引用 - 要么""要么qq{}。但是,这很容易导致令人不快的 SQL 注入,因此强烈建议不要这样做

正如您所发现的,一个更好的解决方案是使用绑定值并让 RDBMS 驱动程序为您处理引用和转义。但是,在这种情况下,您不需要中介 $sth:

$dbh_ora->do(q{UPDATE tbl SET foo = ? WHERE bar = ?}, undef, $new_foo, $bar);

现在,我推断您设置了 RaiseError(很好!),并且您不关心更新的行数,因此您甚至不需要捕获对do().

于 2013-10-24T04:04:10.410 回答
1

对于任何对对我有用的最终解决方案感兴趣的人,这里就是。

sub do_crc_company_performance {

my ($sth_mysql, $sth_oracle);
my $sql_details = <<END_SQL;
select
  tblRecommendations.code,
  tblRecommendations.performance
from 
  crc.tblRecommendations
where
  length(tblRecommendations.code) = '3'
END_SQL


# variables to bind values to
my ($code, $performance);

eval {

    # prepare our select statement for mysql
    $sth_mysql = $dbh_mysql->prepare($sql_details);
    $sth_mysql->execute;
    $sth_mysql->bind_columns(\$code, \$performance);
    # create oracle insertion query

    while ( $sth_mysql->fetch ) {
        $performance = Encode::decode_utf8($performance); # set the flag
        # feed the data into the tblRecommendations table
        $sth_oracle = $dbh_oracle->do('UPDATE tblrecommendations SET performance = ? WHERE code = ?', undef, $performance, $code);
    }
};

if ($@) {
    # what went wrong
    push (@errors, "Unable to update company details: $@");
    # rollback our transaction
}

}

于 2013-10-24T20:29:52.813 回答
0

我在您的代码中没有看到 COMMIT,这是使您的更改永久化所必需的。您想要的某个地方(在每次插入之后或在 fetch 循环之后):

$sth_oracle->commit;

于 2013-10-24T00:49:49.160 回答