在服务器上处理大文件时SSIS脚本任务失败但在本地工作正常

时间:2013-09-25 17:59:15

标签: vb.net ssis

我在SSIS脚本组件中使用VB.Net语言来擦除数据。 (Visual Studio 2010)

以下是代码:

Public Sub Main()
    Dim pk As New Package
    Dim file As New System.IO.StreamReader(Dts.Variables("User::str_SourcePath").Value.ToString())
    Dim data As String
    data = file.ReadToEnd()
    data = data.Replace("'", "")
    data = data.Replace(Chr(0), "")
    data = data.Replace(Chr(1), "")
    file.Close()
    Dim writer As New System.IO.StreamWriter(Dts.Variables("User::str_SourcePath").Value.ToString(), False)
    writer.Write(data)
    writer.Flush()
    writer.Close()

    Dts.TaskResult = ScriptResults.Success
End Sub

当我在本地运行它时,即使存在非常大的文件,该脚本任务也会成功运行,但只有在处理大文件(即超过100 MB)时,服务器上部署的程序包才会失败。(SQL Server 2012)

3 个答案:

答案 0 :(得分:0)

尽管你没有错误消息,我假设你丢失了内存错误。

您有什么选择可以解决?

在问题上投入更多硬件。

确保以64位模式执行程序包(这会妨碍使用JET / Excel驱动程序)。如果你的内存不足,可以在框中添加更多内容,或者在ETL运行之前执行某些内容以释放内存。

修复您的代码

现在,您的代码正在将文件的整个内容读入内存以开始替换。

修复A

字符串是不可变的,这意味着您拥有的每个字符串都位于内存中。我的理解是你没有data的1份副本,因为你执行的操作,你有4个不同的副本。如果您使用的是StringBuilder类,那么它应该更适合您的内存。

修复B

以块的形式读取数据。是的,这是你负责的更多编码,但由于你不能在这个问题上投入更多的硬件,你必须放弃做坏事。每个循环的A读取和写入擦洗线应该足够了。

答案 1 :(得分:0)

您应该一次读取和写入1行,这通常更快,并且几乎不使用任何内存。

Public Sub Main()
    Dim pk As New Package
    Dim file As New System.IO.StreamReader(Dts.Variables("User::str_SourcePath").Value.ToString())
    'Must save it to a temp file since you cannot update the file you are reading.
    Dim sTempFile As String = "c:\temp\MyTemp.txt"
    If IO.File.Exists(sTempFile) Then IO.File.Delete(sTempFile)
    Dim writer As New System.IO.StreamWriter(sTempFile, False)
    Dim data As String
    While Not file.EndOfStream
        data = file.ReadLine
        data = data.Replace("'", "")
        data = data.Replace(Chr(0), "")
        data = data.Replace(Chr(1), "")

        writer.WriteLine(data)
    End While
    file.Close()
    writer.Flush()
    writer.Close()
    'Rename (move) your temp file to the original name
    If IO.File.Exists(Dts.Variables("User::str_SourcePath").Value.ToString()) Then IO.File.Delete(Dts.Variables("User::str_SourcePath").Value.ToString())
    IO.File.Move(sTempFile, Dts.Variables("User::str_SourcePath").Value.ToString())

    Dts.TaskResult = ScriptResults.Success
End Sub

答案 2 :(得分:0)