我使用以下脚本将转储文件上传到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");
答案 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";