SQL 作业中的错误,调用的目标已引发异常

Posted

技术标签:

【中文标题】SQL 作业中的错误,调用的目标已引发异常【英文标题】:Error in a SQL Job, Exception has been thrown by the target of an invocation 【发布时间】:2021-01-18 08:28:14 【问题描述】:

我在 SSIS 项目中遇到了一个大问题。

当我在 SSIS 本地机器中执行项目时,dtsx 运行良好,但是当我将它放入 SQL 代理作业时,它会抛出一个错误:

来源:文件夹中的文件?说明:调用的目标已引发异常。结束错误错误:2020-10-02 17:37:05.33 代码:0x00000001 源:脚本任务 1 描述:调用目标已引发异常。结束错误 DTExec:包执行返回 DTSER_FAILURE (1)。开始时间:17:37:01 结束时间:17:37:05 经过时间:3.687 秒。包执行失败。步骤失败。

文件夹中的源文件是一个脚本任务,代码如下:

    Dim StrFolderArrary As String()
    Dim StrFileArray As String()
    Dim fileName As String
    Dim RemoteDirectory As String

    RemoteDirectory = Dts.Variables("User::ftp_masks").Value.ToString()

    Dim cm As ConnectionManager = Dts.Connections("FTP Connection Manager") 'FTP connection manager name
    Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing))

    Try
        ftp.Connect() 'Connecting to FTP Server

        ftp.SetWorkingDirectory(RemoteDirectory) 'Provide the Directory on which you are working on FTP Server

        ftp.GetListing(StrFolderArrary, StrFileArray) 'Get all the files and Folders List

        'If there is no file in the folder, strFile Arry will contain nothing, so close the connection.

        If StrFileArray Is Nothing Then

            MessageBox.Show(Dts.Variables("User::FileExistsFlg").Value.ToString())

            Dts.Variables("User::FileExistsFlg").Value = 0

            ftp.Close()


            'If Files are there, Loop through the StrFileArray arrary and insert into table
        Else

            For Each fileName In StrFileArray

                MessageBox.Show(fileName)
                Dts.Variables("User::files").Value = fileName
                MessageBox.Show(Dts.Variables("User::files").Value.ToString())
                If fileName = Dts.Variables("User::files").Value.ToString() Then
                    Dts.Variables("User::FileExistsFlg").Value = 1
                    MessageBox.Show(Dts.Variables("User::FileExistsFlg").Value.ToString())
                End If
            Next
            Dts.TaskResult = ScriptResults.Success

            ftp.Close()

        End If

        MessageBox.Show("End try")

    Catch ex As Exception

        MessageBox.Show("Catch")
        Dts.Events.FireError(0, "My File Task", ex.Message, String.Empty, 0)
        MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
        Throw New ApplicationException("Something happened :(", ex)
        'Dts.TaskResult = ScriptResults.Failure
    Finally
        ' This line executes whether or not the exception occurs.
        MessageBox.Show("in Finally block")

    End Try

    '
    ' Add your code here
    '
    Dts.TaskResult = ScriptResults.Success

有人可以帮助我吗? 如何查看具体错误?

感谢您的宝贵时间。

【问题讨论】:

【参考方案1】:

您的代码面临的挑战之一是 MessageBox 的使用。那是一个交互式 UI 元素。当 SSIS 包在无人值守模式下运行时,您不能使用它们,因为服务器上会出现一个弹出窗口,阻止所有进度,直到有人登录并单击“确定”。是的,这完全发生在 DTS 时代(2005 年之前)。

保留弹出窗口的一种方法是测试 InteractiveMode 的系统范围变量。您需要在 ReadOnly 变量列表中检查它,然后将您的代码修改为

VB近似

' This is not valid VB syntax but I can't remember their declaration/initialization sytnax
Dim interactiveMode as Boolean =  (bool) Dts.Variables["System::InteractiveMode"].Value

if interactiveMode then
    MessageBox.Show(fileName)
End If

比这更好的方法是raise Information messages。这些工作都在无人值守模式下进行。

这是C#,欢迎转换成VB语法

bool fireAgain = false;
string message = "0:1";

Dts.Events.FireInformation(0, "SCR Echo Back", string.Format(message, "RemoteDirectory", RemoteDirectory), string.Empty, 0, ref fireAgain);

Dts.Events.FireInformation(0, "SCR Echo Back", string.Format(message, "fileName", fileName), string.Empty, 0, ref fireAgain);

这会将远程目录和文件名值转储到信息日志中。在 VS 中,这将显示在“输出”窗口以及“包执行结果”图形窗口中。在服务器上,这将转储到SSISDB.catalog.OperationMessages

说了这么多,还有什么可能发生的?

我好像记得如果文件夹为空,ftp 客户端会抛出异常。 服务器可能有防火墙/防病毒软件阻止对端口 22/23 的出站访问 (ftp)。 您的连接管理器实例化可能会引发异常 与 ftp 客户端连接相同。 如果这不是匿名访问,则可能是服务器版本的代码没有获取凭据信息,因为它在部署时已从基础包中擦除

【讨论】:

谢谢你的回答我明天试试,我会尝试转换成c#。 在这里:string.Format(message, "RemoteDirectory", RemoteDirectory), string.Empty, 0, ref fireAgain); RemoteDirectory 是我的 ftp 目录吗? RemoteDirectory = Dts.Variables("User::ftp_masks").Value.ToString() 但是其中的逻辑是记录任何面包屑,以便在意外情况发生时找出变量的状态 当然,还有一个外部的 try/catch 块作为一个包罗万象的东西,你可以在其中重复这个逻辑,以防代码不应该爆炸,这样做

以上是关于SQL 作业中的错误,调用的目标已引发异常的主要内容,如果未能解决你的问题,请参考以下文章

调用目标引发的运行时错误豁免

Active Directory - 调用的目标已引发异常

获取“调用的目标已引发异常。”在自定义控件中

PL/SQL 异常和错误处理

解析日期在云函数中执行的创建作业中引发错误

PL/SQL 异常 ORA-06511 游标已打开