Aracılığıyla paylaş


Özel hedef Bileşen geliştirme

Microsoft SQL Server Integration Services gives developers the ability to write custom destination components that can connect to and store data in any custom data source.Özel hedef bileşenleri varolan kaynak bileşenler kullanılarak erişilemez durumda veri kaynaklarına bağlanmak gerektiğinde yararlı Integration Services.

Hedef bileşenleri bir veya daha fazla girdi ve sıfır çıkışları vardır.Tasarım sırasında saat, bunlar oluşturup bağlantıları yapılandırmak ve sütun meta veriler dış veri kaynağından okuyun.Yürütme sırasında bunlar, dış veri kaynağına bağlanmak kaynak ve bileşenlerden upstream veri akışı dış için alınan veri satırları ekleme kaynak.Bileşen yürütme önce dış veri kaynak varsa, hedef bileşeni ayrıca bileşenin alan sütunların veri türleri dış veri kaynağına sütunların veri türlerini eşleştiğinden emin olun.

Bu bölümde, nasıl hedef bileşenleri geliştir ayrıntılarını anlatır ve önemli kavramları açıklığa kavuşturmak için kod örnekleri sağlar.Hedef bileşen örneği için bkz: Integration Services örnekleri üzerinde Codeplex.Genel bir bakış için veri akışı bileşeni geliştirme, bkz: Bir özel veri akışı Bileşen geliştirme.

Tasarım zamanı

Tasarım - uygulamasaat bileşeni düzgün yapılandırılmış olduğunu doğrulama ve bir dış veri kaynağına bir bağlantı belirterek bir hedef bileşeni işlevselliği içerir.Tanım olarak, bir hedef bileşeni tek bir girdi ve büyük olasılıkla bir hata çıktı vardır.

Bileşeni oluşturma

Hedef bileşenleri kullanarak dış veri kaynaklarına bağlanmak ConnectionManager nesnelerin tanımlanmış bir paket.Gereksinim için bir Bağlantı Yöneticisi için hedef bileşeni gösterir SSIS Tasarımcısı ve kullanıcılar için bir öğe ekleyerek bileşenin, RuntimeConnectionCollection koleksiyon , ComponentMetaData.Bu koleksiyon, iki amaca hizmet eder: ilk olarak, bir Bağlantı Yöneticisi ihtiyacını bildirir SSIS Tasarımcısı; daha sonra kullanıcı seçilen veya Bağlantı Yöneticisi oluşturulan sonra Bağlantı Yöneticisi'nde bir başvuru sakladığı paket şu anda kullanılan bileşen tarafından.Zaman bir IDTSRuntimeConnection100 koleksiyonuna eklenir Gelişmiş Düzenleyici görüntüler Bağlantı özelliklerini sekmesini seçin veya bir bağlantı oluşturmak için kullanıcıdan, paket bileşen tarafından kullanılacak.

Aşağıdaki kod örneği uygulaması gösterir ProvideComponentProperties , bir giriş ekler ve sonra ekler bir IDTSRuntimeConnection100 itiraz RuntimeConnectionCollection.

using System;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime;

namespace Microsoft.Samples.SqlServer.Dts
{
    [DtsPipelineComponent(DisplayName = "Destination Component",ComponentType =ComponentType.DestinationAdapter)]
    public class DestinationComponent : PipelineComponent 
    {
        public override void ProvideComponentProperties()
        {
            // Reset the component.
            base.RemoveAllInputsOutputsAndCustomProperties();
            ComponentMetaData.RuntimeConnectionCollection.RemoveAll();

            IDTSInput100 input = ComponentMetaData.InputCollection.New();
            input.Name = "Input";

            IDTSRuntimeConnection100 connection = ComponentMetaData.RuntimeConnectionCollection.New();
            connection.Name = "ADO.net";
        }
    }
}
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports Microsoft.SqlServer.Dts.Pipeline
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime

Namespace Microsoft.Samples.SqlServer.Dts

    <DtsPipelineComponent(DisplayName:="Destination Component", ComponentType:=ComponentType.DestinationAdapter)> _
    Public Class DestinationComponent
        Inherits PipelineComponent

        Public Overrides Sub ProvideComponentProperties()

            ' Reset the component.
            Me.RemoveAllInputsOutputsAndCustomProperties()
            ComponentMetaData.RuntimeConnectionCollection.RemoveAll()

            Dim input As IDTSInput100 = ComponentMetaData.InputCollection.New()
            input.Name = "Input"

            Dim connection As IDTSRuntimeConnection100 = ComponentMetaData.RuntimeConnectionCollection.New()
            connection.Name = "ADO.net"

        End Sub
    End Class
End Namespace

Bir dış veri kaynağına bağlanma

Bir bağlantı için eklendikten sonra RuntimeConnectionCollection, geçersiz kılma, AcquireConnections yöntem bağlantısı için dış veri kaynak.Tasarım zamanında bu yöntem çaðrýlýr saat ve çalışma saat.Bileşen çalışma tarafından belirtilen Bağlantı Yöneticisi bağlantısı gerekirsaat , bağlantı ve daha sonra dış veri kaynağına.Bir kez kurulduğunda, bileşen bağlantı dahili olarak önbelleğe alır ve serbest zaman ReleaseConnections denir.Geliştiriciler bu yöntem geçersiz kılmak ve sırasında bileşen tarafından kurulan bağlantı serbest AcquireConnections.Bu yöntemlerin her ikisi de ReleaseConnections ve AcquireConnections, adı verilir tasarım saat ve çalışma saat.

Aşağıdaki kod örneği, bir ado bağlayan bir bileşeni gösterir.Ağ Bağlantısı'nda AcquireConnections yöntem, sonra bağlantıyı kapatır ve ReleaseConnections.

using Microsoft.SqlServer.Dts.Runtime.Wrapper;

private SqlConnection sqlConnection;

public override void AcquireConnections(object transaction)
{
    if (ComponentMetaData.RuntimeConnectionCollection[0].ConnectionManager != null)
    {
        ConnectionManager cm = Microsoft.SqlServer.Dts.Runtime.DtsConvert.GetWrapper(ComponentMetaData.RuntimeConnectionCollection[0].ConnectionManager);
        ConnectionManagerAdoNet cmado = cm.InnerObject as ConnectionManagerAdoNet;

        if (cmado == null)
            throw new Exception("The ConnectionManager " + cm.Name + " is not an ADO.NET connection.");

        sqlConnection = cmado.AcquireConnection(transaction) as SqlConnection;
        sqlConnection.Open();
    }
}

public override void ReleaseConnections()
{
    if (sqlConnection != null && sqlConnection.State != ConnectionState.Closed)
        sqlConnection.Close();
}
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper

Private sqlConnection As SqlConnection

Public Overrides Sub AcquireConnections(ByVal transaction As Object)

    If IsNothing(ComponentMetaData.RuntimeConnectionCollection(0).ConnectionManager) = False Then

        Dim cm As ConnectionManager = DtsConvert.GetWrapper(ComponentMetaData.RuntimeConnectionCollection(0).ConnectionManager)
        Dim cmado As ConnectionManagerAdoNet = CType(cm.InnerObject,ConnectionManagerAdoNet)

        If IsNothing(cmado) Then
            Throw New Exception("The ConnectionManager " + cm.Name + " is not an ADO.NET connection.")
        End If

        sqlConnection = CType(cmado.AcquireConnection(transaction), SqlConnection)
        sqlConnection.Open()

    End If
End Sub

Public Overrides Sub ReleaseConnections()

    If IsNothing(sqlConnection) = False And sqlConnection.State <> ConnectionState.Closed Then
        sqlConnection.Close()
    End If

End Sub

Bileşen doğrulanıyor

Hedef bileşen geliştiricileri açıklandığı gibi doğrulama gerçekleştirmek Bileşen doğrulaması.Buna ek olarak, kullanıcılar verileri bileşenin giriş sütununda tanımlanan sütun özellikleri yazın doğrulamanız gerekir koleksiyon dış veri kaynak adresindeki sütunlarla eşleşmesi.Zaman zaman karşı dış veri giriş sütunları doğrulama kaynak imkansız ya da ne zaman gibi istenmeyen olabilir bileşen veya SSIS Tasarımcısı olan bağlantısı kesilmiş veya gidiş gelişler kabul edilemez.Bu gibi durumlarda sütun giriş sütun koleksiyon hala kullanılarak doğrulanabilir ExternalMetadataColumnCollection giriş nesnesi.

Bu koleksiyon, giriş ve çıkış nesneler üzerinde bulunmaktadır ve dış veri kaynak adresindeki sütunlarından bileşen geliştirici tarafından doldurulmuş olması gerekir.Bu koleksiyon giriş sütunları doğrulamak için kullanılan, SSIS Tasarımcısı çevrimdışı, bileşen bağlantısı kesilmiş veya zaman ValidateExternalMetadata özellik false.

Aşağıdaki örnek kodu bir dış meta veriler ekler sütun varolan bir girdiye dayalı sütun.

private void AddExternalMetaDataColumn(IDTSInput100 input,IDTSInputColumn100 inputColumn)
{
    // Set the properties of the external metadata column.
    IDTSExternalMetadataColumn100 externalColumn = input.ExternalMetadataColumnCollection.New();
    externalColumn.Name = inputColumn.Name;
    externalColumn.Precision = inputColumn.Precision;
    externalColumn.Length = inputColumn.Length;
    externalColumn.DataType = inputColumn.DataType;
    externalColumn.Scale = inputColumn.Scale;

    // Map the external column to the input column.
    inputColumn.ExternalMetadataColumnID = externalColumn.ID;
}
Private Sub AddExternalMetaDataColumn(ByVal input As IDTSInput100, ByVal inputColumn As IDTSInputColumn100)

    ' Set the properties of the external metadata column.
    Dim externalColumn As IDTSExternalMetadataColumn100 = input.ExternalMetadataColumnCollection.New()
    externalColumn.Name = inputColumn.Name
    externalColumn.Precision = inputColumn.Precision
    externalColumn.Length = inputColumn.Length
    externalColumn.DataType = inputColumn.DataType
    externalColumn.Scale = inputColumn.Scale

    ' Map the external column to the input column.
    inputColumn.ExternalMetadataColumnID = externalColumn.ID

End Sub

Çalışma zamanı

Yürütme sırasında hedef bileşeni bir çağrı alır ProcessInput yöntem her saat tam PipelineBuffer edinilebilir ters yönde bir bileşen.Kadar daha fazla arabellek kullanılabilir sürekli olarak bu yöntem çağrılır ve EndOfRowset özellik true.Sırasında bu yöntem hedef bileşenleri arabelleğindeki satır ve sütunları okumak ve onları dış veri ekleme kaynak.

Sütunları arabellekte bulma

Bir bileşen için giriş arabelleği çıktı sütunu koleksiyonları bileşenlerinden upstream bileşeni tanımlanan tüm sütunlar içeren veri akışı.Hedef bileşeni yalnızca iki sütun yazacak bile, örneğin, kaynak bileşen çıktısı üç sütundaki sağlar ve ek çıktı sütununun sonraki bileşen ekler, hedef bileşeni için sağlanan arabellek dört sütun içerir.

Sipariş giriş arabelleği sütun giriş sütun sütun dizini tarafından tanımlanan koleksiyon hedef bileşeni.Sütunlar güvenilir bir şekilde bulunması bir arabellek satırda yalnızca kullanarak FindColumnByLineageID yöntem, BufferManager.Bu yöntem, belirtilen arabellek belirtilen lineage Kimliğine sahip ve satırın konumunu döndürür sütun bulur.Giriş sütun dizinleri genellikle sırasında bulunan PreExecute yöntem ve daha sonra sırasında kullanmak için geliştirici tarafından önbelleğe alınmış ProcessInput.

Aşağıdaki kod örneği sırasında arabellek giriş sütunları konumunu bulur PreExecute ve depolar bunları bir dizi.Dizi sonradan sırasında kullanılan ProcessInput sütun değerlerini okumak içinarabellek.

int[] cols;

public override void PreExecute()
{
    IDTSInput100 input = ComponentMetaData.InputCollection[0];

    cols = new int[input.InputColumnCollection.Count];

    for (int x = 0; x < input.InputColumnCollection.Count; x++)
    {
        cols[x] = BufferManager.FindColumnByLineageID(input.Buffer, input.InputColumnCollection[x].LineageID);
    }
}
Private cols As Integer()

Public Overrides Sub PreExecute()

    Dim input As IDTSInput100 = ComponentMetaData.InputCollection(0)

    ReDim cols(input.InputColumnCollection.Count)

    For x As Integer = 0 To input.InputColumnCollection.Count

        cols(x) = BufferManager.FindColumnByLineageID(input.Buffer, input.InputColumnCollection(x).LineageID)
    Next x

End Sub

Satır işleniyor

Giriş sütunları arabellekte bulunan bir kez onlar okunabilir ve dış veriler için yazılmış kaynak.

Hedef bileşeni için dış veri satırları yazdığı sırada kaynak, "satır okuma" güncelleştirmek isteyebilirsiniz. ya da "blob bayt okuma" performans sayaçları çağırarak IncrementPipelinePerfCounter yöntem.Daha fazla bilgi için bkz: Veri akışı altyapısı performansını izleme.

Aşağıdaki örnek, sağlanan arabellek satırları okur bir bileşeni gösterir ProcessInput.Arabellek sütun dizinleri sırasında bulunan PreExecute önceki kod örneği.

public override void ProcessInput(int inputID, PipelineBuffer buffer)
{
        while (buffer.NextRow())
        {
            foreach (int col in cols)
            {
                if (!buffer.IsNull(col))
                {
                    //  TODO: Read the column data.
                }
            }
        }
}
Public Overrides Sub ProcessInput(ByVal inputID As Integer, ByVal buffer As PipelineBuffer)

        While (buffer.NextRow())

            For Each col As Integer In cols

                If buffer.IsNull(col) = False Then

                    '  TODO: Read the column data.
                End If

            Next col
        End While
End Sub

Örnek

Aşağıdaki örnek Bağlantı Yöneticisi ikili veri dosyalarına veri akışı kaydetmek için bir dosya kullanan basit bir hedef bileşeni gösterir.Bu örnek, tüm yöntemleri ve bu konuda tartışılan işlevselliğini göstermektedir.Her özel hedef bileşeni geçersiz kılmak gerekir, ancak Tasarım - kodunu içeren önemli yöntemler gösterilmiştirsaat doğrulama.Görmek için daha eksiksiz bir örnek hedef bileşeni, Readme_DatasetDestination Component Sample.

using System;
using System.IO;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;

namespace BlobDst
{
  [DtsPipelineComponent(DisplayName = "BLOB Extractor Destination", Description = "Writes values of BLOB columns to files")]
  public class BlobDst : PipelineComponent
  {
    string m_DestDir;
    int m_FileNameColumnIndex = -1;
    int m_BlobColumnIndex = -1;

    public override void ProvideComponentProperties()
    {
      IDTSInput100 input = ComponentMetaData.InputCollection.New();
      input.Name = "BLOB Extractor Destination Input";
      input.HasSideEffects = true;

      IDTSRuntimeConnection100 conn = ComponentMetaData.RuntimeConnectionCollection.New();
      conn.Name = "FileConnection";
    }

    public override void AcquireConnections(object transaction)
    {
      IDTSRuntimeConnection100 conn = ComponentMetaData.RuntimeConnectionCollection[0];
      m_DestDir = (string)conn.ConnectionManager.AcquireConnection(null);

      if (m_DestDir.Length > 0 && m_DestDir[m_DestDir.Length - 1] != '\\')
        m_DestDir += "\\";
    }

    public override IDTSInputColumn100 SetUsageType(int inputID, IDTSVirtualInput100 virtualInput, int lineageID, DTSUsageType usageType)
    {
      IDTSInputColumn100 inputColumn = base.SetUsageType(inputID, virtualInput, lineageID, usageType);
      IDTSCustomProperty100 custProp;

      custProp = inputColumn.CustomPropertyCollection.New();
      custProp.Name = "IsFileName";
      custProp.Value = (object)false;

      custProp = inputColumn.CustomPropertyCollection.New();
      custProp.Name = "IsBLOB";
      custProp.Value = (object)false;

      return inputColumn;
    }

    public override void PreExecute()
    {
      IDTSInput100 input = ComponentMetaData.InputCollection[0];
      IDTSInputColumnCollection100 inputColumns = input.InputColumnCollection;
      IDTSCustomProperty100 custProp;

      foreach (IDTSInputColumn100 column in inputColumns)
      {
        custProp = column.CustomPropertyCollection["IsFileName"];
        if ((bool)custProp.Value == true)
        {
          m_FileNameColumnIndex = (int)BufferManager.FindColumnByLineageID(input.Buffer, column.LineageID);
        }

        custProp = column.CustomPropertyCollection["IsBLOB"];
        if ((bool)custProp.Value == true)
        {
          m_BlobColumnIndex = (int)BufferManager.FindColumnByLineageID(input.Buffer, column.LineageID);
        }
      }
    }

    public override void ProcessInput(int inputID, PipelineBuffer buffer)
    {
      while (buffer.NextRow())
      {
        string strFileName = buffer.GetString(m_FileNameColumnIndex);
        int blobLength = (int)buffer.GetBlobLength(m_BlobColumnIndex);
        byte[] blobData = buffer.GetBlobData(m_BlobColumnIndex, 0, blobLength);

        strFileName = TranslateFileName(strFileName);

        // Make sure directory exists before creating file.
        FileInfo fi = new FileInfo(strFileName);
        if (!fi.Directory.Exists)
          fi.Directory.Create();

        // Write the data to the file.
        FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write, FileShare.None);
        fs.Write(blobData, 0, blobLength);
        fs.Close();
      }
    }

    private string TranslateFileName(string fileName)
    {
      if (fileName.Length > 2 && fileName[1] == ':')
        return m_DestDir + fileName.Substring(3, fileName.Length - 3);
      else
        return m_DestDir + fileName;
    }
  }
}
Imports System 
Imports System.IO 
Imports Microsoft.SqlServer.Dts.Pipeline 
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper 
Namespace BlobDst 

 <DtsPipelineComponent(DisplayName="BLOB Extractor Destination", Description="Writes values of BLOB columns to files")> _ 
 Public Class BlobDst 
 Inherits PipelineComponent 
   Private m_DestDir As String 
   Private m_FileNameColumnIndex As Integer = -1 
   Private m_BlobColumnIndex As Integer = -1 

   Public  Overrides Sub ProvideComponentProperties() 
     Dim input As IDTSInput100 = ComponentMetaData.InputCollection.New 
     input.Name = "BLOB Extractor Destination Input" 
     input.HasSideEffects = True 
     Dim conn As IDTSRuntimeConnection100 = ComponentMetaData.RuntimeConnectionCollection.New 
     conn.Name = "FileConnection" 
   End Sub 

   Public  Overrides Sub AcquireConnections(ByVal transaction As Object) 
     Dim conn As IDTSRuntimeConnection100 = ComponentMetaData.RuntimeConnectionCollection(0) 
     m_DestDir = CType(conn.ConnectionManager.AcquireConnection(Nothing), String) 
     If m_DestDir.Length > 0 AndAlso Not (m_DestDir(m_DestDir.Length - 1) = "\"C) Then 
       m_DestDir += "\" 
     End If 
   End Sub 

   Public  Overrides Function SetUsageType(ByVal inputID As Integer, ByVal virtualInput As IDTSVirtualInput100, ByVal lineageID As Integer, ByVal usageType As DTSUsageType) As IDTSInputColumn100 
     Dim inputColumn As IDTSInputColumn100 = MyBase.SetUsageType(inputID, virtualInput, lineageID, usageType) 
     Dim custProp As IDTSCustomProperty100 
     custProp = inputColumn.CustomPropertyCollection.New 
     custProp.Name = "IsFileName" 
     custProp.Value = CType(False, Object) 
     custProp = inputColumn.CustomPropertyCollection.New 
     custProp.Name = "IsBLOB" 
     custProp.Value = CType(False, Object) 
     Return inputColumn 
   End Function 

   Public  Overrides Sub PreExecute() 
     Dim input As IDTSInput100 = ComponentMetaData.InputCollection(0) 
     Dim inputColumns As IDTSInputColumnCollection100 = input.InputColumnCollection 
     Dim custProp As IDTSCustomProperty100 
     For Each column As IDTSInputColumn100 In inputColumns 
       custProp = column.CustomPropertyCollection("IsFileName") 
       If CType(custProp.Value, Boolean) = True Then 
         m_FileNameColumnIndex = CType(BufferManager.FindColumnByLineageID(input.Buffer, column.LineageID), Integer) 
       End If 
       custProp = column.CustomPropertyCollection("IsBLOB") 
       If CType(custProp.Value, Boolean) = True Then 
         m_BlobColumnIndex = CType(BufferManager.FindColumnByLineageID(input.Buffer, column.LineageID), Integer) 
       End If 
     Next 
   End Sub 

   Public  Overrides Sub ProcessInput(ByVal inputID As Integer, ByVal buffer As PipelineBuffer) 
     While buffer.NextRow 
       Dim strFileName As String = buffer.GetString(m_FileNameColumnIndex) 
       Dim blobLength As Integer = CType(buffer.GetBlobLength(m_BlobColumnIndex), Integer) 
       Dim blobData As Byte() = buffer.GetBlobData(m_BlobColumnIndex, 0, blobLength) 
       strFileName = TranslateFileName(strFileName) 
       Dim fi As FileInfo = New FileInfo(strFileName) 
       ' Make sure directory exists before creating file.
       If Not fi.Directory.Exists Then 
         fi.Directory.Create 
       End If 
       ' Write the data to the file.
       Dim fs As FileStream = New FileStream(strFileName, FileMode.Create, FileAccess.Write, FileShare.None) 
       fs.Write(blobData, 0, blobLength) 
       fs.Close 
     End While 
   End Sub 

   Private Function TranslateFileName(ByVal fileName As String) As String 
     If fileName.Length > 2 AndAlso fileName(1) = ":"C Then 
       Return m_DestDir + fileName.Substring(3, fileName.Length - 3) 
     Else 
       Return m_DestDir + fileName 
     End If 
   End Function 
 End Class 
End Namespace
Integration Services simgesi (küçük)Integration Services ile güncel kalın

En son karşıdan yüklemeler, makaleler, örnekler ve seçilen topluluk çözümleri yanı sıra Microsoft videolar için ziyaret Integration Services sayfa msdn veya TechNet:

Bu güncelleştirmelerle ilgili otomatik bildirim almak için, sayfadaki RSS akışlarına abone olun.