Aggiunta di attività a livello di programmazioneAdding Tasks Programmatically

È possibile aggiungere attività ai tipi di oggetti seguenti nel motore di runtime:Tasks can be added to the following types of objects in the run-time engine:

  • Package

  • Sequence

  • ForLoop

  • ForEachLoop

  • DtsEventHandler

    Queste classi vengono considerate contenitori ed ereditano tutte la proprietà Executables.These classes are considered containers, and they all inherit the Executables property. I contenitori possono contenere una raccolta di attività, ovvero oggetti eseguibili elaborati dal runtime durante l'esecuzione del contenitore.Containers can contain a collection of tasks, which are executable objects processed by the runtime during execution of the container. L'ordine di esecuzione degli oggetti nella raccolta è determinato da qualsiasi oggetto PrecedenceConstraint impostato su ogni attività nei contenitori.The order of execution of the objects in the collection is determined any PrecedenceConstraint set on each task in the containers. I vincoli di precedenza rendono possibile la diramazione dell'esecuzione in base all'esito positivo, all'esito negativo o al completamento di un oggetto Executable nella raccolta.Precedence constraints enable execution branching based on the success, failure, or completion of an Executable in the collection.

    Ogni contenitore include una raccolta Executables che contiene i singoli oggetti Executable.Each container has an Executables collection that contains the individual Executable objects. Ogni attività eseguibile eredita e implementa il metodo Execute e il metodo Validate.Each executable task inherits and implements the Execute method and Validate method. Questi due metodi vengono chiamati dal motore di runtime per elaborare ogni oggetto Executable.These two methods are called by the run-time engine to process each Executable.

    Per aggiungere un'attività a un pacchetto, è necessario un contenitore con una raccolta Executables esistente.To add a task to a package, you need a container with an Executables existing collection. Nella maggior parte dei casi, l'attività che verrà aggiunta alla raccolta è un pacchetto.Most of the time, the task that you will add to the collection is a package. Per aggiungere la nuova attività eseguibile nella raccolta per tale contenitore, chiamare il Add metodo.To add the new task executable into the collection for that container, you call the Add method . Il metodo include un solo parametro, ovvero una stringa che contiene il CLSID, il PROGID, il moniker STOCK o l'oggetto CreationName dell'attività da aggiungere.The method has a single parameter, a string, that contains the CLSID, PROGID, STOCK moniker, or CreationName of the task you are adding.

Nomi delle attivitàTask Names

Sebbene sia possibile specificare un'attività in base al nome o all'ID, il STOCK del moniker non è il parametro utilizzato più frequentemente nel Add metodo.Although you can specify a task by name or by ID, the STOCK moniker is the parameter used most often in the Add method. Per aggiungere un'attività a un eseguibile identificato dal STOCK moniker, utilizzare la sintassi seguente:To add a task to an executable identified by the STOCK moniker, use the following syntax:

Executable exec = package.Executables.Add("STOCK:BulkInsertTask");  
Dim exec As Executable = package.Executables.Add("STOCK:BulkInsertTask")  

Nell'elenco seguente mostra i nomi per ogni attività utilizzati dopo il STOCK moniker.The following list shows the names for each task that are used after the STOCK moniker.

  • ActiveXScriptTaskActiveXScriptTask

  • BulkInsertTaskBulkInsertTask

  • ExecuteProcessTaskExecuteProcessTask

  • ExecutePackageTaskExecutePackageTask

  • Exec80PackageTaskExec80PackageTask

  • FileSystemTaskFileSystemTask

  • FTPTaskFTPTask

  • MSMQTaskMSMQTask

  • PipelineTaskPipelineTask

  • ScriptTaskScriptTask

  • SendMailTaskSendMailTask

  • SQLTaskSQLTask

  • TransferStoredProceduresTaskTransferStoredProceduresTask

  • TransferLoginsTaskTransferLoginsTask

  • TransferErrorMessagesTaskTransferErrorMessagesTask

  • TransferJobsTaskTransferJobsTask

  • TransferObjectsTaskTransferObjectsTask

  • TransferDatabaseTaskTransferDatabaseTask

  • WebServiceTaskWebServiceTask

  • WmiDataReaderTaskWmiDataReaderTask

  • WmiEventWatcherTaskWmiEventWatcherTask

  • XMLTaskXMLTask

    Se si preferisce una sintassi più esplicita o se l'attività che si desidera aggiungere non include un moniker STOCK, è possibile aggiungere l'attività all'eseguibile utilizzandone il nome lungo.If you prefer a more explicit syntax, or if the task that you want to add does not have a STOCK moniker, you can add the task to the executable using its long name. Questa sintassi richiede anche la specifica del numero di versione dell'attività.This syntax requires that you also specify the version number of the task.

Executable exec = package.Executables.Add(  
  "Microsoft.SqlServer.Dts.Tasks.ScriptTask.ScriptTask, " +  
  "Microsoft.SqlServer.ScriptTask, Version=10.0.000.0, " +  
  "Culture=neutral, PublicKeyToken=89845dcd8080cc91");  
Dim exec As Executable = package.Executables.Add( _  
  "Microsoft.SqlServer.Dts.Tasks.ScriptTask.ScriptTask, " & _  
  "Microsoft.SqlServer.ScriptTask, Version=10.0.000.0, " & _  
  "Culture=neutral, PublicKeyToken=89845dcd8080cc91")  

È possibile ottenere il nome lungo per l'attività a livello di codice, senza la necessità di specificare la versione dell'attività, tramite il AssemblyQualifiedName proprietà della classe, come illustrato nell'esempio seguente.You can obtain the long name for the task programmatically, without having to specify the task version, by using the AssemblyQualifiedName property of the class, as shown in the following example. Per questo esempio è richiesto un riferimento all'assembly Microsoft.SqlServer.SQLTask.This example requires a reference to the Microsoft.SqlServer.SQLTask assembly.

using Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask;  
...  
      Executable exec = package.Executables.Add(  
        typeof(Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ExecuteSQLTask).AssemblyQualifiedName);  
Imports Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask  
...  
    Dim exec As Executable = package.Executables.Add( _  
      GetType(Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ExecuteSQLTask).AssemblyQualifiedName)  

Esempio di codice seguente viene illustrato come creare un Executables raccolta da un nuovo pacchetto, quindi aggiungere un'attività File System e un'attività Inserimento Bulk alla raccolta, usando i relativi STOCK moniker.The following code example shows how to create an Executables collection from a new package, and then add a File System task and a Bulk Insert task to the collection, by using their STOCK monikers. Per questo esempio è richiesto un riferimento agli assembly Microsoft.SqlServer.FileSystemTask e Microsoft.SqlServer.BulkInsertTask.This example requires a reference to the Microsoft.SqlServer.FileSystemTask and Microsoft.SqlServer.BulkInsertTask assemblies.

using System;  
using Microsoft.SqlServer.Dts.Runtime;  
using Microsoft.SqlServer.Dts.Tasks.FileSystemTask;  
using Microsoft.SqlServer.Dts.Tasks.BulkInsertTask;  

namespace Microsoft.SqlServer.Dts.Samples  
{  
  class Program  
  {  
    static void Main(string[] args)  
    {  
      Package p = new Package();  
      // Add a File System task to the package.  
      Executable exec1 = p.Executables.Add("STOCK:FileSystemTask");  
      TaskHost thFileSystemTask = exec1 as TaskHost;  
      // Add a Bulk Insert task to the package.  
      Executable exec2 = p.Executables.Add("STOCK:BulkInsertTask");  
      TaskHost thBulkInsertTask = exec2 as TaskHost;  

      // Iterate through the package Executables collection.  
      Executables pExecs = p.Executables;  
      foreach (Executable pExec in pExecs)  
      {  
        TaskHost taskHost = (TaskHost)pExec;  
        Console.WriteLine("Type {0}", taskHost.InnerObject.ToString());  
      }  
      Console.Read();  
    }  
  }  
}  
Imports Microsoft.SqlServer.Dts.Runtime  
Imports Microsoft.SqlServer.Dts.Tasks.FileSystemTask  
Imports Microsoft.SqlServer.Dts.Tasks.BulkInsertTask  

Module Module1  

  Sub Main()  

    Dim p As Package = New Package()  
    ' Add a File System task to the package.  
    Dim exec1 As Executable = p.Executables.Add("STOCK:FileSystemTask")  
    Dim thFileSystemTask As TaskHost = CType(exec1, TaskHost)  
    ' Add a Bulk Insert task to the package.  
    Dim exec2 As Executable = p.Executables.Add("STOCK:BulkInsertTask")  
    Dim thBulkInsertTask As TaskHost = CType(exec2, TaskHost)  

    ' Iterate through the package Executables collection.  
    Dim pExecs As Executables = p.Executables  
    Dim pExec As Executable  
    For Each pExec In pExecs  
      Dim taskHost As TaskHost = CType(pExec, TaskHost)  
      Console.WriteLine("Type {0}", taskHost.InnerObject.ToString())  
    Next  
    Console.Read()  

  End Sub  

End Module  

Esempio di Output:Sample Output:

Type Microsoft.SqlServer.Dts.Tasks.FileSystemTask.FileSystemTask

Type Microsoft.SqlServer.Dts.Tasks.BulkInsertTask.BulkInsertTask

Contenitore TaskHostTaskHost Container

La classe TaskHost è un contenitore che non viene visualizzato nell'interfaccia utente grafica, ma è molto importante nella programmazione.The TaskHost class is a container that does not appear in the graphical user interface, but is very important in programming. Questa classe è un wrapper per ogni attività.This class is a wrapper for every task. Le attività aggiunte al pacchetto utilizzando il metodo Add come oggetto Executable possono essere sottoposte a cast come oggetto TaskHost.Tasks that are added to the package by using the Add method as an Executable object can be cast as a TaskHost object. Quando si esegue il cast di un'attività come TaskHost, è possibile utilizzare proprietà e metodi aggiuntivi sull'attività.When a task is cast as a TaskHost, you can use additional properties and methods on the task. È inoltre possibile accedere all'attività stessa tramite la proprietà InnerObject di TaskHost.Also, the task itself can be accessed through the InnerObject property of the TaskHost. A seconda delle esigenze, è possibile decidere di mantenere l'attività come oggetto TaskHost in modo da poterne utilizzare le proprietà tramite la raccolta Properties.Depending on your needs, you may decide to keep the task as a TaskHost object so that you can use the properties of the task through the Properties collection. Il vantaggio dell'utilizzo di Properties è la possibilità di scrivere codice più generico.The advantage of using the Properties is that you can write more generic code. Se è necessario codice molto specifico per un'attività, è consigliabile eseguire il cast dell'attività nell'oggetto appropriato.If you need very specific code for a task, then you should cast the task to its appropriate object.

Nell'esempio di codice seguente è illustrato come eseguire il cast di un oggetto TaskHost, thBulkInsertTask, che contiene BulkInsertTask, in un oggetto BulkInsertTask.The following code example shows how to cast a TaskHost, thBulkInsertTask, that contains a BulkInsertTask, to a BulkInsertTask object.

BulkInsertTask myTask = thBulkInsertTask.InnerObject as BulkInsertTask;  
Dim myTask As BulkInsertTask = CType(thBulkInsertTask.InnerObject, BulkInsertTask)  

Nell'esempio di codice seguente è illustrato come eseguire il cast dell'eseguibile in TaskHost, quindi utilizzare la proprietà InnerObject per determinare quale tipo di eseguibile è contenuto nell'host.The following code example shows how to cast the executable to a TaskHost, and then use the InnerObject property to determine which type of executable is contained by the host.

using System;  
using Microsoft.SqlServer.Dts.Runtime;  
using Microsoft.SqlServer.Dts.Tasks.FileSystemTask;  
using Microsoft.SqlServer.Dts.Tasks.BulkInsertTask;  

namespace Microsoft.SqlServer.Dts.Samples  
{  
  class Program  
  {  
    static void Main(string[] args)  
    {  
      Package p = new Package();  
      // Add a File System task to the package.  
      Executable exec1 = p.Executables.Add("STOCK:FileSystemTask");  
      TaskHost thFileSystemTask1 = exec1 as TaskHost;  
      // Add a Bulk Insert task to the package.  
      Executable exec2 = p.Executables.Add("STOCK:BulkInsertTask");  
      TaskHost thFileSystemTask2 = exec2 as TaskHost;  

      // Iterate through the package Executables collection.  
      Executables pExecs = p.Executables;  
      foreach (Executable pExec in pExecs)  
      {  
        TaskHost taskHost = (TaskHost)pExec;  
        if (taskHost.InnerObject is Microsoft.SqlServer.Dts.Tasks.FileSystemTask.FileSystemTask)  
        {  
          // Do work with FileSystemTask here.  
          Console.WriteLine("Found task of type {0}", taskHost.InnerObject.ToString());  
        }  
        else if (taskHost.InnerObject is Microsoft.SqlServer.Dts.Tasks.BulkInsertTask.BulkInsertTask)  
        {  
          // Do work with BulkInsertTask here.  
          Console.WriteLine("Found task of type {0}", taskHost.InnerObject.ToString());  
        }  
        // Add additional statements to check InnerObject, if desired.  
      }  
      Console.Read();  
    }  
  }  
}  
Imports Microsoft.SqlServer.Dts.Runtime  
Imports Microsoft.SqlServer.Dts.Tasks.FileSystemTask  
Imports Microsoft.SqlServer.Dts.Tasks.BulkInsertTask  

Module Module1  

  Sub Main()  

    Dim p As Package = New Package()  
    ' Add a File System task to the package.  
    Dim exec1 As Executable = p.Executables.Add("STOCK:FileSystemTask")  
    Dim thFileSystemTask1 As TaskHost = CType(exec1, TaskHost)  
    ' Add a Bulk Insert task to the package.  
    Dim exec2 As Executable = p.Executables.Add("STOCK:BulkInsertTask")  
    Dim thFileSystemTask2 As TaskHost = CType(exec2, TaskHost)  

    ' Iterate through the package Executables collection.  
    Dim pExecs As Executables = p.Executables  
    Dim pExec As Executable  
    For Each pExec In pExecs  
      Dim taskHost As TaskHost = CType(pExec, TaskHost)  
      If TypeOf taskHost.InnerObject Is Microsoft.SqlServer.Dts.Tasks.FileSystemTask.FileSystemTask Then  
        ' Do work with FileSystemTask here.  
        Console.WriteLine("Found task of type {0}", taskHost.InnerObject.ToString())  
      ElseIf TypeOf taskHost.InnerObject Is Microsoft.SqlServer.Dts.Tasks.BulkInsertTask.BulkInsertTask Then  
        ' Do work with BulkInsertTask here.  
        Console.WriteLine("Found task of type {0}", taskHost.InnerObject.ToString())  
      End If  
      ' Add additional statements to check InnerObject, if desired.  
    Next  
    Console.Read()  

  End Sub  

End Module  

Esempio di Output:Sample Output:

Found task of type Microsoft.SqlServer.Dts.Tasks.FileSystemTask.FileSystemTask

Found task of type Microsoft.SqlServer.Dts.Tasks.BulkInsertTask.BulkInsertTask

L'istruzione Add restituisce un eseguibile di cui viene eseguito il cast in un oggetto TaskHost dall'oggetto Executable appena creato.The Add statement returns an executable that is cast to a TaskHost object from the newly created Executable object.

Per impostare proprietà o chiamare metodi sul nuovo oggetto, sono disponibili due opzioni:To set properties or to call methods on the new object, you have two options:

  1. Utilizzare la raccolta Properties di TaskHost.Use the Properties collection of the TaskHost. Ad esempio, per ottenere una proprietà dall'oggetto, utilizzare th.Properties["propertyname"].GetValue(th)).For example, to obtain a property from the object, use th.Properties["propertyname"].GetValue(th)). Per impostare una proprietà, utilizzare th.Properties["propertyname"].SetValue(th, <value>);.To set a property, use th.Properties["propertyname"].SetValue(th, <value>);.

  2. Eseguire il cast di InnerObject di TaskHost nella classe dell'attività.Cast the InnerObject of the TaskHost to the task class. Ad esempio, per eseguire il cast dell'attività Inserimento bulk in BulkInsertTask dopo che è stata aggiunta a un pacchetto come Executable e successivamente ne è stato eseguito il cast in TaskHost, utilizzare BulkInsertTask myTask = th.InnerObject as BulkInsertTask;.For example, to cast the Bulk Insert task to a BulkInsertTask after it has been added to a package as an Executable and subsequently cast to a TaskHost, use BulkInsertTask myTask = th.InnerObject as BulkInsertTask;.

    L'utilizzo della classe TaskHost nel codice, invece dell'esecuzione del cast nella classe specifica dell'attività, presenta i vantaggi seguenti:Using the TaskHost class in code, instead of casting to the task-specific class has the following advantages:

  • Il provider TaskHost Properties non richiede un riferimento all'assembly nel codice.The TaskHostProperties provider does not require a reference to the assembly in the code.

  • È possibile progettare routine generiche che funzionano per qualsiasi attività, perché non è necessario conoscere il nome dell'attività in fase di compilazione.You can code generic routines that work for any task, because you do not have to know the name of the task at compile time. Tali routine generiche includono i metodi in cui si passa il nome dell'attività al metodo e il codice del metodo funziona per tutte le attività.Such generic routines include methods where you pass in the name of the task to the method, and the method code works for all tasks. Si tratta di un metodo efficace per la scrittura di codice di test.This is a good method for writing test code.

    Esegue il cast dal TaskHost nella classe specifica dell'attività presenta i vantaggi seguenti:Casting from the TaskHost to the task-specific class has the following advantages:

  • Il progetto di Visual Studio rende disponibile il completamento delle istruzioni (IntelliSense).The Visual Studio project gives you statement completion (IntelliSense).

  • È possibile che il codice venga eseguito più velocemente.The code may run faster.

  • Gli oggetti specifici dell'attività consentono l'associazione anticipata e le risultanti ottimizzazioni.Task-specific objects enable early binding and the resulting optimizations. Per ulteriori informazioni sull'associazione anticipata e tardiva, vedere l'argomento corrispondente in Concetti sul linguaggio Visual Basic.For more information about early and late binding, see the topic "Early and Late Binding" in Visual Basic Language Concepts.

    L'esempio di codice seguente si basa sul concetto di riutilizzo del codice dell'attività.The following code example expands on the concept of reusing task code. Anziché eseguire il cast delle attività negli equivalenti specifici della classe, nell'esempio di codice viene illustrato come eseguire il cast dell'eseguibile in un oggetto TaskHost, quindi viene utilizzato Properties per scrivere codice generico per tutte le attività.Instead of casting tasks to their specific class equivalents, the code example shows how to cast the executable to a TaskHost, and then uses the Properties to write generic code against all the tasks.

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

namespace Microsoft.SqlServer.Dts.Samples  
{  
  class Program  
  {  
    static void Main(string[] args)  
    {  
      Package package = new Package();  

      string[] tasks = { "STOCK:SQLTask", "STOCK:ScriptTask",   
        "STOCK:ExecuteProcessTask", "STOCK:PipelineTask",   
        "STOCK:FTPTask", "STOCK:SendMailTask", "STOCK:MSMQTask" };  

      foreach (string s in tasks)  
      {  
        TaskHost taskhost = package.Executables.Add(s) as TaskHost;  
        DtsProperties props = taskhost.Properties;  
        Console.WriteLine("Enumerating properties on " + taskhost.Name);  
        Console.WriteLine(" TaskHost.InnerObject is " + taskhost.InnerObject.ToString());  
        Console.WriteLine();  

        foreach (DtsProperty prop in props)  
        {  
          Console.WriteLine("Properties for " + prop.Name);  
          Console.WriteLine("Name : " + prop.Name);  
          Console.WriteLine("Type : " + prop.Type.ToString());  
          Console.WriteLine("Readable : " + prop.Get.ToString());  
          Console.WriteLine("Writable : " + prop.Set.ToString());  
          Console.WriteLine();  
        }  
      }  
      Console.Read();  
    }  
  }  
}  
Imports Microsoft.SqlServer.Dts.Runtime  

Module Module1  

  Sub Main()  

    Dim package As Package = New Package()  

    Dim tasks() As String = New String() {"STOCK:SQLTask", "STOCK:ScriptTask", _  
              "STOCK:ExecuteProcessTask", "STOCK:PipelineTask", _  
              "STOCK:FTPTask", "STOCK:SendMailTask", "STOCK:MSMQTask"}  

    For Each s As String In tasks  

      Dim taskhost As TaskHost = CType(package.Executables.Add(s), TaskHost)  
      Dim props As DtsProperties = taskhost.Properties  
      Console.WriteLine("Enumerating properties on " & taskhost.Name)  
      Console.WriteLine(" TaskHost.InnerObject is " & taskhost.InnerObject.ToString())  
      Console.WriteLine()  

      For Each prop As DtsProperty In props  
        Console.WriteLine("Properties for " + prop.Name)  
        Console.WriteLine(" Name : " + prop.Name)  
        Console.WriteLine(" Type : " + prop.Type.ToString())  
        Console.WriteLine(" Readable : " + prop.Get.ToString())  
        Console.WriteLine(" Writable : " + prop.Set.ToString())  
        Console.WriteLine()  
      Next  

    Next  
    Console.Read()  

  End Sub  

End Module  

Risorse esterneExternal Resources

Post di blog, Ezapi per SQL Server 2012, su blogs.msdn.com.Blog entry, EzAPI – Updated for SQL Server 2012, on blogs.msdn.com.

Vedere ancheSee Also

Connessione a livello di programmazione di attivitàConnecting Tasks Programmatically