【发布时间】:2024-01-19 04:11:01
【问题描述】:
我在 SSIS 下创建了 Logging,它在我的数据库的系统表中生成为 [dbo].[sysssislog]。我正在尝试将特定列(如 Id、Source、starttime、endtime 和 message)获取到另一个 SQL Server 表、client.EximLog 和Client.EximLogHistory。
每次我运行包时都会抛出以下错误:
在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, Boolean breakConnection, Action1 wrapCloseInAction) 在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔 breakConnection,Action1 wrapCloseInAction) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,布尔调用者HasConnectionLock,布尔异步关闭) 在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean & dataReady) 在 System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(字符串方法名,布尔异步,Int32 超时,布尔异步写入) 在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 完成,字符串方法名,布尔 sendToPipe,Int32 超时,布尔和 usedCache,布尔异步写入,布尔 inRetry) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 ScriptMain.Input0_ProcessInputRow(Input0Buffer 行) 在 UserComponent.Input0_ProcessInput(Input0Buffer 缓冲区) 在 UserComponent.ProcessInput(Int32 InputID,字符串 InputName,PipelineBuffer 缓冲区,OutputNameMap OutputMap) 在 Microsoft.SqlServer.Dts.Pipeline.ScriptComponent.ProcessInput(Int32 InputID,PipelineBuffer 缓冲区) 在 Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost.ProcessInput(Int32 inputID, PipelineBuffer 缓冲区)
我创建了一个事件处理程序“Onerror”来执行数据流任务,例如“连接到 SSIS 日志表”。
在数据流任务中,我使用 OLD DB Connection 连接到 sysssislog 表。
SELECT Id, source, starttime, endtime, message
FROM dbo.sysssislog
WHERE event = 'onerror' AND ID NOT IN (SELECT ISNULL(cast(LogId as int), 0) FROM [Client].[EximLog])
我已将 OLD DB 源连接作为目标连接到脚本组件。我正在执行以下存储过程。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spEximLog]
--Add parameters for the stored procedure
@pSystemID nvarchar(max) = NULL,
--@sEvent nvarchar(max) = NULL,
@pSource nvarchar(max) = NULL,
@pStarttime nvarchar(max) = NULL,
@pEndtime nvarchar(max) = NULL,
@pMessage nvarchar(max) = NULL
WITH EXECUTE AS OWNER
AS
BEGIN
SET NOCOUNT ON;
DECLARE @vJoboutcome nvarchar(max);
DECLARE @vGUID nvarchar(40);
DECLARE @vTimeStamp timestamp;
DECLARE @vEximID int;
DECLARE @vDefaultOperation nvarchar(40);
DECLARE @vDefaultEventRegistrationId int;
DECLARE @vDefaultVersion int;
SET @vJoboutcome = 'F';
SET @vDefaultOperation = 'Insert';
SET @vDefaultEventRegistrationId = 1;
SET @vDefaultVersion = 1;
IF NOT EXISTS (SELECT * FROM [dbo].[sysssislog] WHERE ID = @pSystemID)
BEGIN
SET @vGUID = CAST((SELECT NEWID()) as nvarchar(40));
--Inserting 8 cloumns into Exim table
INSERT INTO [Client].[EXIMLog]
(
[JobName], [JobMessage], [JobOutCome], [LogID], [DtmJobStart], [DtmJobEnd]
, [EventRegistrationId], [ObjectId]
)
VALUES(@pSource, @pMessage, @vJoboutcome, @pSystemID, @pStarttime, @pEndtime
, @vDefaultEventRegistrationId, @vGUID);
SET @vEximID = (SELECT @@IDENTITY); /*Same EximId is used in Malvern import and in its history table*/
--Stores the timestamp for the row using where clause
SET @vTimeStamp = (SELECT [TimeStamp] from [Client].[EXIMLog] where Id = @vEximId);
--Inserting 12 cloumns into Exim History table
INSERT INTO [Client].[EXIMLogHistory]
(
[Id], [Version], [JobName], [JobMessage], [JobOutCome], [LogID], [DtmJobStart]
, [DtmJobEnd], [EventRegistrationId], [ObjectId], [Operation], [TimeStamp]
)
VALUES(@vEximID, @vDefaultVersion, @pSource, @pMessage, @vJoboutcome, @pSystemID, @pStarttime, @pEndtime, @vDefaultEventRegistrationId, @vGUID
, @vDefaultOperation, CAST(@vTimeStamp as varbinary));
END
END;
GO
以下是我在脚本组件中使用的脚本,连接管理器是 ADO.net 连接。
#region Namespaces
using System;
using System.Data.SqlClient;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
#endregion
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
System.Data.SqlClient.SqlConnection conn =
(System.Data.SqlClient.SqlConnection)Connections.SecondConnection.AcquireConnection(null);
System.Data.SqlClient.SqlCommand cmd = new
System.Data.SqlClient.SqlCommand("Exec [dbo].[spEximLog]'" + Row.Id + "', '" + Row.source + "', '" + Row.starttime +"', '" + Row.endtime + "' , '" + Row.message + "'", conn);
cmd.ExecuteNonQuery();
}
【问题讨论】:
-
您发布的“错误”不是错误消息。这是堆栈跟踪。再看一遍,看看你能不能找到真正的错误。
-
我发现 'message' 列的单引号中有一个单词 'spEximlog'。所以改变了传递脚本的方式如下,它起作用了。
标签: c# sql-server logging error-handling ssis