用于从Amazon Oracle RDS下载原始文件的Perl脚本

时间:2015-04-03 11:32:04

标签: oracle perl amazon-web-services rds

我使用以下脚本将转储文件上传到Amazon Oracle RDS实例。这个过程在书中有详细记载。但是在对数据库完成一些工作后,我需要将转储返回。不幸的是,任务的这一方都没有记录。亚马逊没有计划他的客户以简单的方式离开RDS。

请帮助转换此脚本以执行反向作业,即获取文件 FROM Amazon Oracle RDS将其保存到 TO 我的工作站。转储文件是使用Oracle的DBMS_DATAPUMP函数在RDS上准备的。

use DBI;
use warnings;
use strict;

# RDS instance info
my $RDS_PORT  = 1521;
my $RDS_HOST  = "blabla12345.us-west-2.rds.amazonaws.com";
my $RDS_LOGIN = "username/123456";
my $RDS_SID   = "ORCL";

#The $ARGV[0] is a parameter you pass into the script
my $dirname = "DATA_PUMP_DIR";
my $fname   = $ARGV[0];

my $data  = "dummy";
my $chunk = 8192;

my $sql_open   = "BEGIN perl_global.fh := utl_file.fopen(:dirname, :fname, 'wb', :chunk); END;";
my $sql_write  = "BEGIN utl_file.put_raw(perl_global.fh, :data, true); END;";
my $sql_close  = "BEGIN utl_file.fclose(perl_global.fh); END;";
my $sql_global = "create or replace package perl_global as fh utl_file.file_type; end;";

my $conn = DBI->connect(
    'dbi:Oracle:host=' . $RDS_HOST . ';sid=' . $RDS_SID . ';port=' . $RDS_PORT,
    $RDS_LOGIN,
    ''
) || die($DBI::errstr . "\n");

my $updated = $conn->do($sql_global);
my $stmt    = $conn->prepare($sql_open);
$stmt->bind_param_inout(":dirname", \$dirname, 12);
$stmt->bind_param_inout(":fname",   \$fname,   12);
$stmt->bind_param_inout(":chunk",   \$chunk,   4);
$stmt->execute() || die($DBI::errstr . "\n");

open(INF, $fname) || die "\nCan't open $fname for reading: $!\n";
binmode(INF);
$stmt = $conn->prepare($sql_write);
my %attrib = ('ora_type', '24');
my $val = 1;
while ( $val > 0 ) {
    $val = read(INF, $data, $chunk);
    $stmt->bind_param(":data", $data, \%attrib);
    $stmt->execute() || die($DBI::errstr . "\n");
}
die "Problem copying: $!\n" if $!;
close INF || die "Can't close $fname: $!\n";
$stmt = $conn->prepare($sql_close);
$stmt->execute() || die($DBI::errstr . "\n");

2 个答案:

答案 0 :(得分:1)

我发现自己处于完全相同的情况。我没有Perl程序员,翻转这个脚本对我来说太过分了。值得庆幸的是,我找到了一个java程序来从http://wordpress.filefoundry.co.uk/update的RDS检索文件。作者甚至还提供以下附加信息。这对我很有用!

您需要做一些事情来编译和运行程序。

首先,从Oracle获取Java JDK,以便编译软件。 然后运行该软件,您也可以使用JDK。

如果您的服务器上已经安装了Oracle,那么可能已经安装了某个版本的JDK。否则,它是免费下载的。

编译器是javac命令 - 与C#编译器csc.exe完全一样。 它从.java文件生成.class文件,就像csc从.cs文件生成..exe文件一样。

在Windows服务器上,编译命令行的程序 javac DataPumpDownloader.java

它应该在当前目录中生成一个.class文件。

然后,要运行程序,命令行是 java -cp .; ojdbc6.jar DataPumpDownloader主机端口服务用户名密码文件名

您可能需要根据已安装JDK和Oracle JDBC驱动程序的位置调整上述路径。 除了JDK和Oracle JDBC驱动程序之外,您不需要任何其他功能来使其工作。

答案 1 :(得分:0)

我不完美,但工作

# RDS instance info

use DBI;

# Autoflush
$|=1;

$datestring = gmtime();
print "$datestring\n";

my $RDS_PORT=1521;
my $RDS_HOST="orcl.XXXXXXXXXXXXXXXX.eu-west-1.rds.amazonaws.com";
my $RDS_LOGIN="root/XXXXXXXXXXXXX";
my $RDS_SID="ORCL";

my $dirname = "DATA_PUMP_DIR";
my $fname = $ARGV[0];
my $data = "dummy";
my $chunk = 32767;

my $sql_open = "BEGIN perl_global.fh := utl_file.fopen(:dirname, :fname, 'rb', :chunk); END;";
my $sql_read = "BEGIN utl_file.get_raw(perl_global.fh, :data, NULL); END;";
my $sql_close = "BEGIN utl_file.fclose(perl_global.fh); END;";
my $sql_global = "create or replace package perl_global as fh utl_file.file_type; end;";
my $conn = DBI->connect('dbi:Oracle:host='.$RDS_HOST.';sid='.$RDS_SID.';port='.$RDS_PORT,$RDS_LOGIN, '') || die ( $DBI::errstr .  "\n");
my $updated=$conn->do($sql_global);

my $stmt = $conn->prepare ($sql_open);
$stmt->bind_param_inout(":dirname", \$dirname, 12);
$stmt->bind_param_inout(":fname", \$fname, 12);
$stmt->bind_param_inout(":chunk", \$chunk, 4);
$stmt->execute() || die ( $DBI::errstr . "\n");

open (INF, ">:raw" , $fname) || die "\nCan't open $fname for writing: $!\n";
binmode(INF);

$stmt = $conn->prepare ($sql_read);
my %attrib = ('ora_type','24');
my $val=1;
while ($val > 0) {
 $stmt->bind_param_inout(":data", \$data , 32768, \%attrib);
 $stmt->execute() || die ( $DBI::errstr . "\n");
 print INF $data;
 print ".";
};
print "\n";

die "Problem copying: $!\n" if $!;
close INF || die "Can't close $fname: $!\n";
$stmt = $conn->prepare ($sql_close);
$stmt->execute() || die ( $DBI::errstr . "\n");

$datestring = gmtime();
print "$datestring\n";