下载和处理要在Oracle中加载的超大型压缩MS Access文件的最佳方法

Hec*_*hez 7 c# java asp.net oracle oracle10g

我必须下载通过FTP加密的250mb~ZIP文件密码.下载后我必须用一个通用密码解压缩,Zip文件将包含一个1.5GB的MS Access数据库,我必须读取它并与我的数据库Oracle中的某些表进行一些连接,并将该数据转换并加载到该Oracle数据库中.

我正在寻找最好的方法来完成这个过程.我是ac#developer,所以我的第一个想法是使用c#,通过FtpClientFtpWebRequest下载文件,然后使用像DotNetZip这样的zip库并通过ODBC打开MS Access数据库,并使用ODP将记录加载到Oracle.NEt,我认为这是我的"简单方法",因为我知道该怎么做.

但由于这是一个大文件,我知道这可能需要很长时间,我关注时间和效率以及如何减少这个过程的时间.

所以我认为将所有请求直接处理到oracle(从那里下载FTP,在那里解压缩,并直接在那里处理信息会减少将记录从c#传递到oracle的时间)应该减少这个时间过程,但我不确定这是否是正确的方法.

所以我开始研究来自oracle的图书馆,它可以做我想要的事情,我找到了PLSQL-utils,看起来他们可以做我需要的一切,除了阅读MS Access数据库,我开始寻找并发现在异构服务,但我从来没有使用过,所以我有点失去了这一点.

我也听说过我可以直接从Oracle使用Java,我知道java可以通过JDBC连接到MS Access.所以我搜索了一下,发现了一些关于在Oracle数据库中调用Java方法的内容

这就是我到目前为止所做的,但我不知道应该使用哪种方法,我的意思是,据我所知,RDBMS用于处理数据,但不用于编写下载文件之类的东西,这就是为什么我们有OOP的语言.

作为附加信息,此过程将在一个月内执行一次或两次,因此我必须安排它,如果它在oracle中,可以使用计划作业轻松完成,或者在c#中使用计划任务或Windows服务(那些是我知道的工具)

我有一些限制

  • 我的客户端没有MS SQL Server,也没有可以为它购买许可证(所以我不能在这个过程中使用DTSX)
  • 在Oracle生产服务器中,我可能没有足够的权限来完成所有工作,但如果他们是最适合这个过程的我可以遵守这些权限
  • 如果需要后端服务器(Java,c#托管在IIS或WebLogic或JBoss或anykind上),此服务器和Oracle服务器将是不同的
  • Unix服务器上托管的Oracle数据库

说到这一切,如果我使用.net并在Oracle DataBase中按记录加载记录,我怎样才能有效地完成所有这些过程?我应该在甲骨文中做些什么吗?或者这不是吗?有一个更好的方法吗?

Jam*_*mes 2

我认为您使用 C# 控制台应用程序使其成为一个可重复的过程是正确的。是我在许多项目中用于 zip 的很棒的免费库。

using (var client = new WebClient())
using (var stream = client.OpenRead(@"ftp://mysite.com/mydb.zip"))
using (var file = File.Create(@"c:\temp\mydb.zip"))
{
    stream.CopyTo(@"c:\temp\mydb.zip", 32000);
}

using (ZipFile zip = ZipFile.Read(@"c:\temp\mydb.zip"))
{
    ZipEntry e = zip["bigdb.mdb"];
    e.Password = "yourpassword";
    e.Extract("c:\temp\bigdb.mdb");
}
Run Code Online (Sandbox Code Playgroud)

解压后,您可以创建与访问数据库和数据读取器对象的数据连接。然后使用 dbreader 读取行并写入平面文件(避免大数据集出现内存不足异常)。

private constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=yourdbfile.mdb;Jet OLEDB:Database Password=yourpassword;";
OleDbConnection conn = new OleDbConnection(constr);
string query = "SELECT * FROM [YourTable]";

OleDbCommand cmd = new OleDbCommand(query, conn);
OleDbDataReader reader = cmd.ExecuteReader();
int rowNum = 0;
StringBuilder sb = new StringBuilder(); 
while (reader.Read())
{
   // write rows to flat file in chunks of 10K rows.
   sb.Append(reader["FieldA"].ToString() + "|");
   sb.Append(reader["FieldB"].ToString() + "|");
   sb.Append(reader["FieldC"].ToString() + System.Environment.NewLine);

   if (rowNum % 10000 == 0)
   {
        File.AppendText(@"c:\temp\data.psv", sb.ToString());
        sb = new StringBuilder(); 
   }
   rowNum++;
}
File.AppendText(@"c:\temp\data.psv", sb.ToString());
reader.Close();
Run Code Online (Sandbox Code Playgroud)

填充数据表后,您可以将其导出到平面文件。我不建议逐行插入数据,这会非常慢,并且会使 Oracle 数据库事务日志膨胀。我不相信 Oracle 10g 有支持批量加载的 .Net 驱动程序,因此您可能需要通过平面文件批量加载。

接下来,通过命令行导入 Oracle,您可以从 C# 控制台应用程序调用它。在执行此操作之前,您需要创建一个控制文件 ctl.ldr,Oracle 首先使用该文件进行批量加载操作。

options (skip=1)
load data
 INFILE 'c:\temp\data.psv'
 INTO table tblTest
 APPEND
 FIELDS TERMINATED BY "|" optionally enclosed by '"'      
 ( fielda,fieldb,etc...)

and then 
run it in as follows via command line

sqlldr username/pswd@oracle_sid control=ctl.ldr
Run Code Online (Sandbox Code Playgroud)

希望这有帮助,祝你好运!

[编辑]

您还可以查看 .Net Oracle Bulk copy 类。这是随 Oracle 11g客户端驱动程序一起提供的。也许它仍然适用于您的 10g 服务器。一个潜在的问题是,同一应用程序服务器上的所有其他应用程序也需要与这些较新的 11g 客户端驱动程序配合使用。另一种选择是构建一个使用支持批量加载的Jena 框架的Java 应用程序。