【问题标题】:perl update oracle database with values from another databaseperl 使用来自另一个数据库的值更新 oracle 数据库
【发布时间】:2013-10-24 00:26:22
【问题描述】:

我正在编写一个 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);
}

【问题讨论】:

    标签: mysql database oracle perl dbi


    【解决方案1】:

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

    一种解决方案是使用插值引用 - ""qq{}。但是,这很容易导致不愉快的 SQL 注入,因此strongly discouraged

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

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

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

    【讨论】:

      【解决方案2】:

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

      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
      }
      

      }

      【讨论】:

        【解决方案3】:

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

        $sth_oracle-&gt;commit;

        【讨论】:

        • 自动提交已启用。每次运行脚本时,我都删除了提交以消除警告消息。
        • 找到了一种方法来做到这一点。 “$sth_oracle = $dbh_oracle->do('UPDATE tblrecommendations SET performance = ?, updated = ? WHERE code = ?', undef, $performance, $updated, $code);"它可能不是最好的,但它确实有效。明天我能回答我自己的问题时再发帖。
        猜你喜欢
        • 2015-02-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-16
        相关资源
        最近更新 更多