执行 SQL 任务的 SSIS 2008 R2 OnProgress 日志记录会截断 SQL 语句

SSIS 2008 R2 OnProgress logging for Execute SQL tasks truncates SQL statements

我的执行 SQL 任务配置为记录到自动创建的 dbo.sysssislog table。我真的很想在 2K 消息列中记录任何 SQL 语句的全文,但 SSIS 只记录前 40 个字符。有没有办法覆盖该截断?我是否试图解决错误的问题,因为有更好的方法来实现我的目标?

我创建了一个新的(简单的)包来演示我的问题...

执行SQL任务中的表达式

通过 SSIS 生成的过程

将 OnProgress 记录到生成的默认 SSIS table

table中的截断数据(注意省略号)

您所看到的是如何构建默认 OnProgress 记录器的人工制品(以及我从未注意到的东西)。为什么它的结构如此,这对微软来说是一个问题。

如果您显式调用 sp_ssis_addlogentry,那么它会正确地记录最大 nvarchar(2048) 的文本。但是,如果您记录 OnProgress 事件,则传递给存储过程的文本已被事件记录器的内部工作截断。

在您提供的屏幕截图中有两条注意事项。

  1. 您正在组件的表达式构建器中构建字符串。我强烈警告不要这样做,因为一个简单的事实,即如果你在那里有一个不正确的表达式,你就没有能力调试它。在对象上设置断点,太棒了。您仍然 无法检查您构建的内容的值,因为它在对象内部。相反,我发现我在一个变量中构建所有字符串更成功,然后我的任务表达式只是 @[MyVariable]
  2. 在 2012 版之前,表达式有 4k 个字符的限制。您可以初始化和分配大于该长度的字符串,但如果您尝试使用表达式来执行此操作,则它不起作用。我现在不记得它是截断还是完全失败。

关于 tl;wr;

第 1 轮,脚本方法

我创建了两个 SSIS 变量:Query 和 QueryLength。 Query的Value是SSMS

中我运行下面的查询
SELECT REPLICATE('SELECT 100 AS col UNION ALL ', 70) + ' SELECT 0'

查询是一个使用以下表达式的整数值:LEN(@[User::Query]) 它的值应为 1968

我在我的包中添加了一个脚本任务并使用了以下代码

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;

namespace ST_b3643f349be14c7a9d004a35aaa0422e
{
    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        public void Main()
        {
            // User::Query,User::QueryLength
            string query = this.Dts.Variables["User::Query"].Value.ToString();
            string queryLength = this.Dts.Variables["User::QueryLength"].Value.ToString();

            bool fireAgain = false;
            string message = string.Format("Query => {0}", query);
            this.Dts.Events.FireInformation(0, "Query", message, string.Empty, 0, ref fireAgain);
        this.Dts.Events.FireProgress(message, 50, 0, 1, "query", ref fireAgain);

            message = string.Format("QueryLength => {0}", queryLength);
            this.Dts.Events.FireInformation(0, "QueryLength", message, string.Empty, 0, ref fireAgain);
        this.Dts.Events.FireProgress(message, 50, 0, 1, "queryLength", ref fireAgain);

            Dts.TaskResult = (int)ScriptResults.Success;
        }

        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
    }
}

最后,我打开了登录到 SQL 服务器并记录了 OnInformation 和 OnProgress 事件

我执行了包,然后 运行 下面的查询

USE msdb
SELECT
    S.source
,   S.event
,   LEN(S.message) AS lenMsg
,   S.message
FROM
    dbo.sysssislog AS S
WHERE
    S.event = 'OnInformation'
    OR S.event = 'OnProgress';

如您所见,它记录了 40 多个字符。

第二轮,执行SQL任务方法

根据下面的评论,我修改了程序包以使用调用 sp_ssis_addlogentry 的执行 SQL 任务 我仍然将完整消息记录到 messagedbo.sysssislog

下面的Biml代表我的包。安装 BIDS Helper,添加一个空的 Biml 文件并替换它。更正第 3 行中的数据源值并单击生成,然后 woosh 一个工作包。

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <OleDbConnection Name="CM_OLE" ConnectionString="Data Source=localhost\dev2014;Initial Catalog=msdb;Provider=SQLNCLI10.1;Integrated Security=SSPI;Auto Translate=False;" />
    </Connections>
    <Packages>
        <Package ConstraintMode="Linear" Name="so_28101525">
            <Variables>
                <Variable DataType="String" Name="Query">SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 100 AS col UNION ALL SELECT 0</Variable>
                <Variable DataType="Int32" Name="QueryLength" EvaluateAsExpression="true">LEN(@[User::Query])</Variable>
                <Variable DataType="String" Name="EventType" Namespace="Log">OnProgress</Variable>
                <Variable DataType="String" Name="Source" Namespace="Log">OnProgress</Variable>
            </Variables>
            <Tasks>
                <ExecuteSQL ConnectionName="CM_OLE" Name="Log it">
                    <DirectInput>EXECUTE dbo.sp_ssis_addlogentry
    @event = ?
,   @computer = ?
,   @operator = ?
,   @source = ?
,   @sourceid = ?
,   @executionid = ?
,   @starttime = ?
,   @endtime = ?
,   @datacode = 0
,   @databytes = NULL
,   @message = ?;
</DirectInput>
                    <Parameters>
                        <Parameter DataType="String" VariableName="Log.EventType" Name="0" />
                        <Parameter DataType="String" VariableName="System.MachineName" Name="1" />
                        <Parameter DataType="String" VariableName="System.UserName" Name="2" />
                        <Parameter DataType="String" VariableName="Log.Source" Name="3" />
                        <Parameter DataType="String" VariableName="System.ExecutionInstanceGUID" Name="4" />
                        <Parameter DataType="String" VariableName="System.ExecutionInstanceGUID" Name="5" />
                        <Parameter DataType="String" VariableName="System.ContainerStartTime" Name="6" />
                        <Parameter DataType="String" VariableName="System.ContainerStartTime" Name="7" />
                        <Parameter DataType="String" VariableName="User.Query" Name="8" />
                    </Parameters>

                </ExecuteSQL>
            <ExecuteSQL ConnectionName="CM_OLE" Name="Run Query">
                <VariableInput VariableName="User.Query" />
            </ExecuteSQL>
        </Tasks>
        <LogProviders>
            <SqlServerLogProvider ConnectionName="CM_OLE" Name="SQL Log Provider" /> 
        </LogProviders>
        <LogEvents>
            <LogEvent EventName="OnProgress"></LogEvent>
        </LogEvents>
            </Tasks>
        </Package>
    </Packages>
</Biml>

这导致生成此包。

包运行时 运行 探查器跟踪的结果

exec sp_executesql
    N'exec sp_ssis_addlogentry @P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11'
,   N'@P1 nvarchar(4000),@P2 nvarchar(4000),@P3 nvarchar(4000),@P4 nvarchar(4000),@P5 uniqueidentifier,@P6 uniqueidentifier,@P7 datetime2(7),@P8 datetime2(7),@P9 int,@P10 varbinary(8000),@P11 nvarchar(4000)'
,   N'OnProgress'
,   N'Rohan'
,   N'home\billinkc'
,   N'Log it'
,   '795A8317-110B-423E-BFD3-2E90AB021D53'
,   'DE260D62-A2BC-4C19-A48D-CA6526F1B3EC'
,   '2015-01-23 10:28:38'
,   '2015-01-23 10:28:38'
,   100
,   0x
,   N'Executing query "EXECUTE dbo.sp_ssis_addlogentry
        @event = ?
    ,  ...".'

这与手动生成的对 sp_ssis_logentry

的调用形成对比