Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 下载和处理要加载到Oracle中的超大压缩MS Access文件的最佳方法_C#_Java_Asp.net_Oracle_Oracle10g - Fatal编程技术网

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

C# 下载和处理要加载到Oracle中的超大压缩MS Access文件的最佳方法,c#,java,asp.net,oracle,oracle10g,C#,Java,Asp.net,Oracle,Oracle10g,我必须下载一个通过FTP加密的250mb~ZIP文件密码。下载后,我必须使用通用密码将其解压缩,Zip文件将包含一个1.5GB MS Access数据库,我必须读取该数据库,并与Oracle数据库中的某些表进行一些连接,然后将该数据转换并加载到Oracle数据库中 我正在寻找完成这个过程的最佳方法。 我是一名c#开发人员,所以我的第一个想法是使用c#,通过或下载文件,然后使用类似zip的库,通过ODBC打开MS Access数据库,并使用ODP.NEt将记录加载到Oracle,我认为这是我的“简

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

我正在寻找完成这个过程的最佳方法。 我是一名c#开发人员,所以我的第一个想法是使用c#,通过或下载文件,然后使用类似zip的库,通过ODBC打开MS Access数据库,并使用ODP.NEt将记录加载到Oracle,我认为这是我的“简单方法”,因为我知道怎么做

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

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

所以我开始调查oracle的图书馆,这些图书馆可以做我想归档的工作,我发现它们似乎可以做我需要的一切,除了阅读MS Access数据库,我开始查找,发现了,但我从未使用过它们,所以我对此有点迷茫

我还听说我可以直接从Oracle使用Java,我知道Java可以通过JDBC连接到MS Access。所以我搜索了一下,找到了一些关于

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

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

我有一些限制

  • 我的客户机没有MS SQL Server,也无法为其购买许可证(因此我无法在此过程中使用DTSX)
  • 在Oracle生产服务器中,我可能没有足够的权限来做所有事情,但如果这些权限对流程来说是最好的,我可以遵守这些权限
  • 如果需要后端服务器(托管在IIS、WebLogic、JBoss或任何类型上的Java、c#),则此服务器和Oracle服务器将有所不同
  • Unix服务器上托管的Oracle数据库

说到这里,我该如何高效地完成所有这些过程呢?我应该使用.net并在Oracle数据库中逐个记录地加载记录吗?我应该在甲骨文里做所有的事吗?还是什么都不做?有更好的方法吗?

我会创建一个可以调用的应用程序、网页或WCF服务,下载文件,解压缩文件,并将记录逐行直接插入Oracle。我会尽量将所有数据保存在Oracle中。获取并保存它。一旦zip文件被下载,我就不会经常乱动它了

基本上:

数据->处理器应用程序->Oracle


这样事情就可以自动化了。我会用C语言编写处理器

我认为使用C#console应用程序使其成为一个可重复的过程是正确的。这是一个很棒的免费库,我在很多项目中使用过

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");
}
解包后,可以创建到access DB和datareader对象的数据连接。然后使用dbreader读取行并写入平面文件(避免大数据集出现内存不足异常)

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

接下来,通过命令行导入Oracle。在执行此操作之前,您需要先创建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
希望这有帮助,祝你好运

[编辑]


你也可以看看.Net。这是Oracle 11g客户端驱动程序附带的。也许它仍然可以对您的10g服务器起作用。一个潜在的问题是,同一应用服务器上的所有其他应用程序也需要与这些更新的11g客户端驱动程序一起工作。另一种选择是构建一个Java应用程序,该应用程序使用支持批量加载的。

正如我在评论中所问的,可以从oracle创建到另一个数据库的数据库链接。因此,我将创建一个应用程序来下载文件并将其解压缩到一个特定区域(您的oracle服务器可以读取的区域)。 然后,我将按照以下说明设置指向该文件的DBLink 或者像asktom一样

然后,直接从oracle导入数据,读取msAccess数据库。

签出。这基本上是一个类似Java开源SSIS的产品。下载并提取Access db后,此工具将完成其余工作,以便将数据加载到Oracle中。我以前在MySQL中使用过它,它工作得很好,现在有了一个。Pentaho也不需要在您的db服务器上运行,因此这可能是您要寻找的银弹。权衡的结果是会有一些提升时间

另一个可能的选项是,假设您的Oracle服务器正在运行Windows Server,并且您可以将Access文件放在该服务器上本地的某个位置或服务器可以读取的某个位置,则可以执行以下操作

  • 创建一个C#应用程序以下载、提取Access db并将其复制到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
    
    # Parametros
    param([string]$url, [string]$user, [string]$pass, [string]$folder, [string]$fecpro)
    
    
    if (!$fecpro)
    {
        $date = Get-Date
        $date = $date.AddDays(-1)
        $fecpro = '{0:yyyyMMdd}' -f $date
    }
    
    $FtpServer     = "ftp://$url/$fecpro"
    $Username      = $user
    $Password      = $pass
    $RemoteFolder  = $FtpServer
    if (!$folder)
    {
        $LocalFolder   = $pwd.path + "\"
    } 
    else 
    {
        $LocalFolder   = $folder + "\"
        if (-not(Test-Path -Path $LocalFolder))
        {
            New-Item -ItemType Directory -Force -Path $LocalFolder
        }
    }
    Write-Host "Searching *.zip files from $RemoteFolder..."
    
    $existfiles = gci $LocalFolder | Where-Object { $_.name -like "*.zip" }
    
    $cntFile = 0
    $totFiles = 1
    $listFiles = @(0)*$totfiles
    $listFiles[1] = "cs2-" + $fecpro + "-6004-0000-1.zip"
    
    $existfiles = gci $LocalFolder | Where-Object { $_.name -like "*.zip" }
    
    do
    {
        try
        {
            $f_exist = $false
            $cntFile = $cntFile + 1
            if ($existfiles) {
                foreach($file in $existfiles) {
                    $tmpname = $file.name.ToString()
                    $bool = $listFiles[$cntFile].CompareTo($file.name)                              
                    if ($bool -eq 0) {
                        $f_exist = ($f_exist -or $true)
                    } else {
                        $f_exist = ($f_exist -or $false)
                    }
                }
            }
    
            if (!$f_exist -and $rescnt['CNT'] -eq 0) {
                $ftpfile = $RemoteFolder + "/" + $listFiles[$cntFile]
                $FTPRequest1 = [System.Net.FtpWebRequest]::Create($ftpfile)
                $FTPRequest1.Credentials = New-Object System.Net.NetworkCredential($Username,$Password)
                $FTPRequest1.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
                $FTPRequest1.UsePassive = $true
                $FTPRequest1.UseBinary = $true
                $FTPRequest1.KeepAlive = $false
                $destfile = $LocalFolder + $listFiles[$cntFile]
                $file = New-Object IO.FileStream ($destfile, [IO.FileMode]::Create)
                $FTPResponse = $FTPRequest1.GetResponse()
                $ResponseStream = $FTPResponse.GetResponseStream()
                [byte[]] $buffer = New-Object byte[] 64
                $FTPReader = $ResponseStream.Read($buffer, 0, 64)
                while($FTPReader -ne 0){
                    $FTPReader = $ResponseStream.Read($buffer,0, 64)
                    $file.Write($buffer,0,$FTPReader)
                }
                Write-Host "File $ftpfile is downloaded in local folder."       
                $file.Close()               
                $FTPReader.Close()
                $FTPResponse.Close()
                $ResponseStream.Close()
    
            } 
            else {
                    Write-Host "The file $name already exists in local folder."
            }
        }
        catch
        {
            if ($file) {
                $file.Close()
            }
    
        }
    }
    while ($cntFile -lt $totFiles+1) 
    
    param([string]$folder_origen, [string]$folder_destino, [string]$fecpro)
    
    $P_FOLDER = $folder_origen + "\"
    $P_DESTINO = $folder_destino + "\"
    
    if (!$fecpro)
    {
        $date = Get-Date
        $date = $date.AddDays(-1)
        $fecpro = '{0:yyyyMMdd}' -f $date
    }
    
    Write-Host "Searching *.zip files in $P_FOLDER"
    
    # Inicio del programa
    $LocalFolder = $P_FOLDER + "*$fecpro*.zip"
    $filelocation = gci $LocalFolder
    foreach ($file in $filelocation){
        if (($file) -and ($file.length -gt 0kb))
        {
            $shell = new-object -com shell.application
            $filename = $file.name.ToString()
            $split = $filename.Split(".")
            $dest = $P_DESTINO + $split[0]
            If (!(Test-Path $dest))
            { 
                New-Item $dest -Type Directory
            }
            $orifile = $P_FOLDER + $filename
            $time = "{0:hh_mm_ss.ffff}" -f (get-date)
            $prefile = "d." + (get-date).ToShortDateString() + ".t." + $time
            $prefile = $prefile -replace "/", "_"
            $filename = $prefile + ".f." + $filename
            $P_DESTZIP = $P_FOLDER + "proc" + "\"
            If (!(Test-Path $P_DESTZIP))
            { 
                New-Item $P_DESTZIP -Type Directory
            }
            #Copy-Item $orifile "$P_DESTZIP$prefile_$filename"
            $zipname = $orifile
            #"$P_DESTZIP$prefile_$filename"
            $zip = $shell.NameSpace($zipname)
            $destn = $shell.Namespace($dest)
    
            unzip -o -qq $zipname "*$fecpro*afsbjdtl.*" "*$fecpro*afgnled.bin" -d $dest
    
            Write-Host "$orifile was renamed and unzipped."
        } else
        {
            Write-Host "Zip files not found in the folder."
        }
    }