Dela via


Läser in utdata från ett lokalt paket

gäller för:SQL Server SSIS Integration Runtime i Azure Data Factory

Klientprogram kan läsa utdata från Integration Services-paket när utdata sparas till SQL Server-mål med hjälp av ADO.NET, eller när utdata sparas till ett platt filmål med hjälp av klasserna i System.IO namnområdet. Men ett klientprogram kan också läsa utdata från ett paket direkt från minnet, utan att behöva ett mellanliggande steg för att bevara data. Nyckeln till den här lösningen är Microsoft.SqlServer.Dts.DtsClient namnområde, som innehåller specialiserade implementeringar av IDbConnection, IDbCommandoch IDbDataParameter gränssnitt från System.Data namnrymd. Sammansättningen Microsoft.SqlServer.Dts.DtsClient.dll installeras som standard i %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn.

Viktig

Proceduren som beskrivs i den här artikeln, som använder DtsClient-biblioteket, fungerar endast för paket som distribueras med paketdistributionsmodellen (dvs. med alternativet /SQL, /DTSeller /File). Den här proceduren fungerar inte för paket som distribueras med serverdistributionsmodellen (det vill: med alternativet /ISServer). Om du vill använda utdata från ett lokalt paket som distribuerats med serverdistributionsmodellen (dvs. med alternativet /ISServer) använder du dataströmningsmål i stället för proceduren som beskrivs i den här artikeln.

Not

Proceduren som beskrivs i det här avsnittet kräver att egenskapen DelayValidation för dataflödesaktiviteten och för överordnade objekt anges till standardvärdet False.

Beskrivning

Den här proceduren visar hur du utvecklar ett klientprogram i hanterad kod som läser in utdata från ett paket med ett DataReader-mål direkt från minnet. Stegen som sammanfattas här visas i kodexemplet som följer.

Läsa in datapaketutdata till ett klientprogram

  1. I paketet konfigurerar du ett DataReader-mål för att ta emot utdata som du vill läsa in i klientprogrammet. Ge DataReader-målet ett beskrivande namn, eftersom du kommer att använda det här namnet senare i klientprogrammet. Anteckna namnet på DataReader-målet.

  2. I utvecklingsprojektet anger du en referens till Microsoft.SqlServer.Dts.DtsClient namnområde genom att hitta sammansättningen Microsoft.SqlServer.Dts.DtsClient.dll. Som standard installeras den här sammansättningen i C:\Program Files\Microsoft SQL Server\100\DTS\Binn. Importera namnområdet till koden med hjälp av C# Using eller Visual Basic Imports-instruktionen.

  3. I koden skapar du ett objekt av typen DtsClient.DtsConnection med en anslutningssträng som innehåller de kommandoradsparametrar som krävs av dtexec.exe för att köra paketet. Mer information finns i dtexec Utility. Öppna sedan anslutningen med den här anslutningssträngen. Du kan också använda verktyget dtexecui för att skapa den nödvändiga anslutningssträngen visuellt.

    Not

    Exempelkoden visar hur paketet läses in från filsystemet med hjälp av syntaxen /FILE <path and filename>. Men du kan också läsa in paketet från MSDB-databasen med hjälp av /SQL <package name>-syntaxen eller från Integration Services-paketarkivet med hjälp av /DTS \<folder name>\<package name> syntax.

  4. Skapa ett objekt av typen DtsClient.DtsCommand som använder den tidigare skapade DtsConnection och ange egenskapen CommandText till namnet på DataReader-målet i paketet. Anropa sedan ExecuteReader-metoden för kommandoobjektet för att läsa in paketresultatet till en ny DataReader.

  5. Du kan också indirekt parametrisera utdata från paketet med hjälp av samlingen med DtsDataParameter objekt på DtsCommand- objekt för att skicka värden till variabler som definierats i paketet. I paketet kan du använda dessa variabler som frågeparametrar eller i uttryck för att påverka resultatet som returneras till DataReader-målet. Du måste definiera dessa variabler i paketet i DtsClient namnrymd innan du kan använda dem med DtsDataParameter-objektet från ett klientprogram. (Du kan behöva klicka på knappen Välj variabelkolumner verktygsfältet i fönstret Variabler för att visa namnområde kolumn.) När du i klientkoden lägger till en DtsDataParameter- i samlingen Parameters för DtsCommandutelämnar du namnområdesreferensen DtsClient från variabelnamnet. Till exempel:

    command.Parameters.Add(new DtsDataParameter("MyVariable", 1));  
    
  6. Anropa metoden Read för DataReader upprepade gånger efter behov för att loopa igenom raderna med utdata. Använd data eller spara data för senare användning i klientprogrammet.

    Viktig

    Metoden Read för den här implementeringen av DataReader returnerar sant en gång till efter att den sista dataraden har lästs. Detta gör det svårt att använda den vanliga koden som loopar via DataReader medan Read returnerar sant. Om koden försöker stänga DataReader eller anslutningen efter att ha läst det förväntade antalet rader, utan ytterligare ett slutligt anrop till metoden Read, skapar koden ett ohanterat undantag. Men om koden försöker läsa data på den här slutliga iterationen via en loop, när Read fortfarande returnerar sant men den sista raden har skickats, genererar koden en ohanterad ApplicationException med meddelandet "SSIS IDataReader är förbi slutet av resultatuppsättningen." Det här beteendet skiljer sig från andra DataReader-implementeringar. När du använder en loop för att läsa igenom raderna i DataReader medan Read returnerar truemåste du därför skriva kod för att fånga, testa och ignorera den förväntade ApplicationException- vid det senaste lyckade anropet till metoden Read. Om du i förväg vet hur många rader som förväntas kan du bearbeta raderna och sedan anropa metoden Läs en gång till innan du stänger DataReader och anslutningen.

  7. Anropa metoden Dispose för objektet DtsCommand. Detta är särskilt viktigt om du har använt någon DtsDataParameter objekt.

  8. Stäng DataReader och anslutningsobjekten.

Exempel

I följande exempel körs ett paket som beräknar ett enda aggregeringsvärde och sparar värdet till ett DataReader-mål, och läser sedan det här värdet från DataReader och visar värdet i en textruta i ett Windows-formulär.

Användning av parametrar krävs inte vid inläsning av utdata från ett paket till ett klientprogram. Om du inte vill använda en parameter kan du utelämna användningen av variabeln i namnområdet DtsClient och utelämna koden som använder DtsDataParameter-objektet.

Så här skapar du testpaketet

  1. Skapa ett nytt Integration Services-paket. Exempelkoden använder "DtsClientWParamPkg.dtsx" som namnet på paketet.

  2. Lägg till en variabel av typen Sträng i namnområdet DtsClient. Exempelkoden använder Land som namnet på variabeln. (Du kan behöva klicka på knappen Välj variabelkolumner verktygsfältet i fönstret Variabler för att visa namnområde kolumn.)

  3. Lägg till en OLE DB-anslutningshanterare som ansluter till AdventureWorks2022-exempeldatabasen.

  4. Lägg till en dataflödesaktivitet i paketet och växla till dataflödesdesignytan.

  5. Lägg till en OLE DB-källa i dataflödet och konfigurera den så att den använder den OLE DB-anslutningshanterare som skapades tidigare och följande SQL-kommando:

    SELECT * FROM Sales.vIndividualCustomer WHERE CountryRegionName = ?  
    
  6. Klicka på Parametrar och mappa den enskilda indataparametern i frågan Parameter0 i dialogrutan Ange frågeparametrar till variabeln DtsClient::Country.

  7. Lägg till en aggregeringstransformering i dataflödet och anslut utdata från OLE DB-källan till omvandlingen. Öppna Redigeraren för aggregerad omvandling och konfigurera den så att den utför en "Count all"-åtgärd på alla indatakolumner (*) och för att mata ut det aggregerade värdet med aliaset CustomerCount.

  8. Lägg till ett DataReader-mål i dataflödet och anslut utdata från den aggregerade omvandlingen till DataReader-målet. Exempelkoden använder "DataReaderDest" som namnet på DataReader. Välj den enda tillgängliga indatakolumnen CustomerCount för målet.

  9. Spara paketet. Testprogrammet som skapas härnäst kör paketet och hämtar utdata direkt från minnet.

Så här skapar du testprogrammet

  1. Skapa ett nytt Windows Forms-program.

  2. Lägg till en referens till Microsoft.SqlServer.Dts.DtsClient namnområde genom att bläddra till sammansättningen med samma namn i %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn.

  3. Kopiera och klistra in följande exempelkod i kodmodulen för formuläret.

  4. Ändra värdet för dtexecArgs variabel efter behov så att den innehåller de kommandoradsparametrar som krävs av dtexec.exe för att köra paketet. Exempelkoden läser in paketet från filsystemet.

  5. Ändra värdet för dataReaderName variabel efter behov så att den innehåller namnet på DataReader-målet i paketet.

  6. Placera en knapp och en textruta i formuläret. Exempelkoden använder btnRun som namnet på knappen och txtResults som namnet på textrutan.

  7. Kör programmet och klicka på knappen. Efter en kort paus medan paketet körs bör du se det aggregeringsvärde som beräknas av paketet (antalet kunder i Kanada) som visas i textrutan i formuläret.

Exempelkod

Imports System.Data  
Imports Microsoft.SqlServer.Dts.DtsClient  
  
Public Class Form1  
  
  Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click  
  
    Dim dtexecArgs As String  
    Dim dataReaderName As String  
    Dim countryName As String  
  
    Dim dtsConnection As DtsConnection  
    Dim dtsCommand As DtsCommand  
    Dim dtsDataReader As IDataReader  
    Dim dtsParameter As DtsDataParameter  
  
    Windows.Forms.Cursor.Current = Cursors.WaitCursor  
  
    dtexecArgs = "/FILE ""C:\...\DtsClientWParamPkg.dtsx"""  
    dataReaderName = "DataReaderDest"  
    countryName = "Canada"  
  
    dtsConnection = New DtsConnection()  
    With dtsConnection  
      .ConnectionString = dtexecArgs  
      .Open()  
    End With  
  
    dtsCommand = New DtsCommand(dtsConnection)  
    dtsCommand.CommandText = dataReaderName  
  
    dtsParameter = New DtsDataParameter("Country", DbType.String)  
    dtsParameter.Direction = ParameterDirection.Input  
    dtsCommand.Parameters.Add(dtsParameter)  
  
    dtsParameter.Value = countryName  
  
    dtsDataReader = dtsCommand.ExecuteReader(CommandBehavior.Default)  
  
    With dtsDataReader  
      .Read()  
      txtResults.Text = .GetInt32(0).ToString("N0")  
    End With  
  
    'After reaching the end of data rows,  
    ' call the Read method one more time.  
    Try  
      dtsDataReader.Read()  
    Catch ex As Exception  
      MessageBox.Show("Exception on final call to Read method:" & ControlChars.CrLf & _  
      ex.Message & ControlChars.CrLf & _  
      ex.InnerException.Message, "Exception on final call to Read method", _  
      MessageBoxButtons.OK, MessageBoxIcon.Error)  
    End Try  
  
    ' The following method is a best practice, and is  
    '  required when using DtsDataParameter objects.  
    dtsCommand.Dispose()  
  
    Try  
      dtsDataReader.Close()  
    Catch ex As Exception  
      MessageBox.Show("Exception closing DataReader:" & ControlChars.CrLf & _  
      ex.Message & ControlChars.CrLf & _  
      ex.InnerException.Message, "Exception closing DataReader", _  
      MessageBoxButtons.OK, MessageBoxIcon.Error)  
    End Try  
  
    Try  
      dtsConnection.Close()  
    Catch ex As Exception  
      MessageBox.Show("Exception closing connection:" & ControlChars.CrLf & _  
      ex.Message & ControlChars.CrLf & _  
      ex.InnerException.Message, "Exception closing connection", _  
      MessageBoxButtons.OK, MessageBoxIcon.Error)  
    End Try  
  
    Windows.Forms.Cursor.Current = Cursors.Default  
  
  End Sub  
  
End Class  
using System;  
using System.Windows.Forms;  
using System.Data;  
using Microsoft.SqlServer.Dts.DtsClient;  
  
namespace DtsClientWParamCS  
{  
  public partial class Form1 : Form  
  {  
    public Form1()  
    {  
      InitializeComponent();  
      this.btnRun.Click += new System.EventHandler(this.btnRun_Click);  
    }  
  
    private void btnRun_Click(object sender, EventArgs e)  
    {  
      string dtexecArgs;  
      string dataReaderName;  
      string countryName;  
  
      DtsConnection dtsConnection;  
      DtsCommand dtsCommand;  
      IDataReader dtsDataReader;  
      DtsDataParameter dtsParameter;  
  
      Cursor.Current = Cursors.WaitCursor;  
  
      dtexecArgs = @"/FILE ""C:\...\DtsClientWParamPkg.dtsx""";  
      dataReaderName = "DataReaderDest";  
      countryName = "Canada";  
  
      dtsConnection = new DtsConnection();  
      {  
        dtsConnection.ConnectionString = dtexecArgs;  
        dtsConnection.Open();  
      }  
  
      dtsCommand = new DtsCommand(dtsConnection);  
      dtsCommand.CommandText = dataReaderName;  
  
      dtsParameter = new DtsDataParameter("Country", DbType.String);  
      dtsParameter.Direction = ParameterDirection.Input;  
      dtsCommand.Parameters.Add(dtsParameter);  
  
      dtsParameter.Value = countryName;  
  
      dtsDataReader = dtsCommand.ExecuteReader(CommandBehavior.Default);  
  
      {  
        dtsDataReader.Read();  
        txtResults.Text = dtsDataReader.GetInt32(0).ToString("N0");  
      }  
  
      //After reaching the end of data rows,  
      // call the Read method one more time.  
      try  
      {  
        dtsDataReader.Read();  
      }  
      catch (Exception ex)  
      {  
        MessageBox.Show(  
          "Exception on final call to Read method:\n" + ex.Message + "\n" + ex.InnerException.Message,  
          "Exception on final call to Read method", MessageBoxButtons.OK, MessageBoxIcon.Error);  
      }  
  
      // The following method is a best practice, and is  
      //  required when using DtsDataParameter objects.  
      dtsCommand.Dispose();  
  
      try  
      {  
        dtsDataReader.Close();  
      }  
      catch (Exception ex)  
      {  
        MessageBox.Show(  
          "Exception closing DataReader:\n" + ex.Message + "\n" + ex.InnerException.Message,  
          "Exception closing DataReader", MessageBoxButtons.OK, MessageBoxIcon.Error);  
      }  
  
      try  
      {  
        dtsConnection.Close();  
      }  
      catch (Exception ex)  
      {  
        MessageBox.Show(  
          "Exception closing connection:\n" + ex.Message + "\n" + ex.InnerException.Message,  
          "Exception closing connection", MessageBoxButtons.OK, MessageBoxIcon.Error);  
      }  
  
      Cursor.Current = Cursors.Default;  
  
    }  
  }  
}  

Se även

Förstå skillnaderna mellan lokal körning och fjärrkörning
Läser in och kör ett lokalt paket programmatiskt
läser in och kör ett fjärrpaket programmatiskt