验证数据流组件

PipelineComponent 基类的 Validate 方法用于防止执行未正确配置的组件。使用此方法可验证组件是否具有预期数量的输入和输出对象,组件的自定义属性是否具有可接受的值,以及所需的任何连接是否都已指定。使用此方法还可以验证输入和输出集合中的列是否具有正确的数据类型,以及是否为组件正确设置了每列的 DTSUsageType。基类实现通过检查组件的输入列集合并确保该集合中的每一列都引用上游组件的 IDTSOutputCollection100 中的一列来支持验证过程。

Validate 方法

在 SSIS 设计器中编辑组件时,系统会反复调用 Validate 方法。通过 DTSValidationStatus 枚举返回的值以及发布警告和错误,可以向设计器和组件用户提供反馈。DTSValidationStatus 枚举包含三个指示各种失败阶段的值,还有第四个值,即 VS_ISVALID,它指示组件是否配置正确并且可以执行。

VS_NEEDSNEWMETADATA 值指示在 ComponentMetaData 中存在错误,并且组件可以修复这些错误。如果组件遇到它可修复的元数据错误,它不应在 Validate 方法中修复该错误,并且不应在验证期间修改 ComponentMetaData。如本节后面所述,Validate 方法应只返回 VS_NEEDSNEWMETADATA,并且组件应在对 ReinitializeMetaData 方法的调用中修复该错误。

VS_ISBROKEN 值指示组件具有可通过在设计器中进行编辑来更正的错误。导致该错误的原因通常是没有指定或没有正确设置自定义属性或所需连接。

最后一个错误值是 VS_ISCORRUPT,它指示组件已发现仅应该在编辑包 XML 或使用对象模型直接修改 ComponentMetaData 属性时出现的错误。例如,当组件只添加了一个输入,但是验证操作却发现 ComponentMetaData 中存在多个输入时,此类错误将会发生。生成此返回值的错误只能通过使用**“高级编辑器”对话框中的“重置”**按钮重置组件才能修复。

除了返回错误值,组件还通过在验证过程中发布警告和错误来提供反馈。FireWarningFireError 方法提供了此机制。调用这些方法时,这些事件会发布在 Business Intelligence Development Studio 的**“错误列表”**窗口中。然后,组件开发人员可以直接向用户提供有关已发生错误的反馈,并且在适当的情况下说明如何更正它们。

下面的代码示例演示 Validate 的重写实现。

public override DTSValidationStatus Validate()
{
    bool pbCancel = false;

    // Validate that there is one input.
    if (ComponentMetaData.InputCollection.Count != 1)
    {
    ComponentMetaData.FireError(0, ComponentMetaData.Name, "Incorrect number of inputs.", "", 0, out pbCancel);
    return DTSValidationStatus.VS_ISCORRUPT;
    }

    // Validate that the UserName custom property is set.
    if (ComponentMetaData.CustomPropertyCollection["UserName"].Value == null || ((string)ComponentMetaData.CustomPropertyCollection["UserName"].Value).Length == 0)
    {
        ComponentMetaData.FireError(0, ComponentMetaData.Name, "The UserName property must be set.", "", 0, out pbCancel);
        return DTSValidationStatus.VS_ISBROKEN;
    }

    // Validate that there is one output.
    if (ComponentMetaData.OutputCollection.Count != 1)
    {
        ComponentMetaData.FireError(0, ComponentMetaData.Name, "Incorrect number of outputs.", "", 0, out pbCancel);
        return DTSValidationStatus.VS_ISCORRUPT;
    }

    // Let the base class verify that the input column reflects the output 
    // of the upstream component.
    return base.Validate();
}
Public  Overrides Function Validate() As DTSValidationStatus 

 Dim pbCancel As Boolean = False 


 ' Validate that there is one input.
 If Not (ComponentMetaData.InputCollection.Count = 1) Then 
   ComponentMetaData.FireError(0, ComponentMetaData.Name, "Incorrect number of inputs.", "", 0, pbCancel) 
   Return DTSValidationStatus.VS_ISCORRUPT 
 End If 

 ' Validate that the UserName custom property is set.
 If ComponentMetaData.CustomPropertyCollection("UserName").Value Is Nothing OrElse CType(ComponentMetaData.CustomPropertyCollection("UserName").Value, String).Length = 0 Then 
   ComponentMetaData.FireError(0, ComponentMetaData.Name, "The UserName property must be set.", "", 0, pbCancel) 
   Return DTSValidationStatus.VS_ISBROKEN 
 End If 

 ' Validate that there is one output.
 If Not (ComponentMetaData.OutputCollection.Count = 1) Then 
   ComponentMetaData.FireError(0, ComponentMetaData.Name, "Incorrect number of outputs.", "", 0, pbCancel) 
   Return DTSValidationStatus.VS_ISCORRUPT 
 End If 

 ' Let the base class verify that the input column reflects the output 
 ' of the upstream component.

 Return MyBase.Validate 

End Function

ReinitializeMetaData 方法

每当组件从 Validate 方法返回 VS_NEEDSNEWMETADATA,SSIS 时,设计器都会调用 ReinitializeMetaData 方法。组件应包含用于检测和更正在验证过程中由组件标识的错误的代码。

下面的示例演示一个在验证过程中检测错误并在 ReinitializeMetaData 方法中修复这些错误的组件。

private bool areInputColumnsValid = true;
public override DTSValidationStatus Validate()
{
    IDTSInput100 input = ComponentMetaData.InputCollection[0];
    IDTSVirtualInput100 vInput = input.GetVirtualInput();

    bool Cancel = false;
    foreach (IDTSInputColumn100 column in input.InputColumnCollection)
    {
        try
        {
            IDTSVirtualInputColumn100 vColumn = vInput.VirtualInputColumnCollection.GetVirtualInputColumnByLineageID(column.LineageID);
        }
        catch
        {
            ComponentMetaData.FireError(0, ComponentMetaData.Name, "The input column " + column.IdentificationString + " does not match a column in the upstream component.", "", 0, out Cancel);
            areInputColumnsValid = false;
            return DTSValidationStatus.VS_NEEDSNEWMETADATA;
        }
    }

    return DTSValidationStatus.VS_ISVALID;
}
public override void ReinitializeMetaData()
{
    if (!areInputColumnsValid)
    {
        IDTSInput100 input = ComponentMetaData.InputCollection[0];
        IDTSVirtualInput100 vInput = input.GetVirtualInput();

        foreach (IDTSInputColumn100 column in input.InputColumnCollection)
        {
            IDTSVirtualInputColumn100 vColumn = vInput.VirtualInputColumnCollection.GetVirtualInputColumnByLineageID(column.LineageID);

            if (vColumn == null)
                input.InputColumnCollection.RemoveObjectByID(column.ID);
        }
        areInputColumnsValid = true;
    }
}
Private areInputColumnsValid As Boolean = True 

Public  Overrides Function Validate() As DTSValidationStatus 
 Dim input As IDTSInput100 = ComponentMetaData.InputCollection(0) 
 Dim vInput As IDTSVirtualInput100 = input.GetVirtualInput 
 Dim Cancel As Boolean = False 
 For Each column As IDTSInputColumn100 In input.InputColumnCollection 
   Try 
     Dim vColumn As IDTSVirtualInputColumn100 = vInput.VirtualInputColumnCollection.GetVirtualInputColumnByLineageID(column.LineageID) 
   Catch 
     ComponentMetaData.FireError(0, ComponentMetaData.Name, "The input column " + column.IdentificationString + " does not match a column in the upstream component.", "", 0, Cancel) 
     areInputColumnsValid = False 
     Return DTSValidationStatus.VS_NEEDSNEWMETADATA 
   End Try 
 Next 
 Return DTSValidationStatus.VS_ISVALID 
End Function 

Public  Overrides Sub ReinitializeMetaData() 
 If Not areInputColumnsValid Then 
   Dim input As IDTSInput100 = ComponentMetaData.InputCollection(0) 
   Dim vInput As IDTSVirtualInput100 = input.GetVirtualInput 
   For Each column As IDTSInputColumn100 In input.InputColumnCollection 
     Dim vColumn As IDTSVirtualInputColumn100 = vInput.VirtualInputColumnCollection.GetVirtualInputColumnByLineageID(column.LineageID) 
     If vColumn Is Nothing Then 
       input.InputColumnCollection.RemoveObjectByID(column.ID) 
     End If 
   Next 
   areInputColumnsValid = True 
 End If 
End Sub
Integration Services 图标(小) 使 Integration Services 保持最新

若要从 Microsoft 获得最新的下载内容、文章、示例和视频,以及从社区获得所选解决方案,请访问 MSDN 或 TechNet 上的 Integration Services 页:

若要获得有关这些更新的自动通知,请订阅该页上提供的 RSS 源。