我在SSIS下创建了Logging,它在我的数据库的系统表中生成为[dbo].[sysssislog]
。我试图获取Id,Source,starttime,endtime和message等特定列到另一个SQL Server表,client.EximLog和Client.EximLogHistory
。
每次运行包时都会抛出以下错误:
at System.Data.SqlClient.SqlConnection.OnError(SqlException异常,Boolean breakConnection,Action1 wrapCloseInAction) 在System.Data.SqlClient.SqlInternalConnection.OnError(SqlException异常,Boolean breakConnection,Action1 wrapCloseInAction) 在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose) 在System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean& dataReady) 在System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName,Boolean async,Int32 timeout,Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion,String methodName,Boolean sendToPipe,Int32 timeout,Boolean& usedCache,Boolean asyncWrite,Boolean inRetry) 在System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在ScriptMain.Input0_ProcessInputRow(Input0Buffer Row) 在UserComponent.Input0_ProcessInput(Input0Buffer Buffer) at UserComponent.ProcessInput(Int32 InputID,String InputName,PipelineBuffer Buffer,OutputNameMap OutputMap) 在Microsoft.SqlServer.Dts.Pipeline.ScriptComponent.ProcessInput(Int32 InputID,PipelineBuffer buffer) 在Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost.ProcessInput(Int32 inputID,PipelineBuffer buffer)
我创建了一个事件处理程序'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源连接连接到Script组件作为Destination。我正在执行以下存储过程。
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();
}
答案 0 :(得分:1)
更改脚本组件代码如下并解决了问题。
public override void PostExecute()
{
base.PostExecute();
conn.Close();
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
if(conn.State != System.Data.ConnectionState.Open)
{
conn.Open();
}
System.Data.SqlClient.SqlCommand cmd = new
System.Data.SqlClient.SqlCommand("[dbo].[spEximLog]", conn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@pSystemID", Row.Id));
cmd.Parameters.Add(new SqlParameter("@pSource", Row.source));
cmd.Parameters.Add(new SqlParameter("@pstarttime", Row.starttime));
cmd.Parameters.Add(new SqlParameter("@pendtime", Row.endtime));
cmd.Parameters.Add(new SqlParameter("@pmessage", Row.message));
cmd.ExecuteNonQuery();
}
独立分配参数。在post执行中关闭连接,以便它不会达到最大连接池。