準備查詢變更資料

在執行累加式變更資料載入之 Integration Services 封裝的控制流程中,第三個工作,也就是最後一個工作是準備查詢變更資料,並加入「資料流程」工作。

[!附註]

控制流程的第二個工作是確保所選間隔的變更資料已就緒。如需有關這項工作的詳細資訊,請參閱<判斷變更資料是否就緒>。如需設計控制流程之完整程序的描述,請參閱<利用異動資料擷取改善累加式載入>。

若要查看示範如何在封裝中使用異動資料擷取的完整範例,請參閱<Codeplex>中的 Integration Services 範例。

設計考量

若要擷取異動資料,您將呼叫 Transact-SQL 資料表值函式,接受間隔的端點做為輸入參數,並傳回指定之間隔的異動資料。資料流程中的來源元件會呼叫這個函數。如需有關此來源元件的詳細資訊,請參閱<擷取與了解變更資料>。

最常用的 Integration Services 來源元件 (包括 OLE DB 來源、ADO 來源和 ADO NET 來源) 無法衍生資料表值函式的參數資訊。因此,多數來源無法直接呼叫參數化的函數。

您有兩個設計選項,可傳遞函數的輸入參數:

  • 將參數化的查詢組合成字串。您可以使用「指令碼」工作或「執行 SQL」工作,利用硬式編碼到字串的參數值,組合動態 SQL 字串。然後,您可以將此字串儲存在封裝變數中,並將其用於設定來源元件的 SqlCommand 屬性。由於來源元件不再需要參數資訊,因此這個方式會成功。

    [!附註]

    先行編譯的指令碼所產生的負擔比「執行 SQL」工作所產生的負擔少。

  • 使用參數化的包裝函式。或者,您可以建立參數化的預存程序,當做呼叫參數化資料表值函式的包裝函式。由於來源元件可以成功衍生預存程序的參數資訊,因此這個方式會成功。

本主題使用第一個設計選項,並將參數化的查詢組合成字串。

準備查詢

在您可以將輸入參數的值串連到單一查詢字串前,您必須設定查詢所需的封裝變數。

設定封裝變數

  • 在 Business Intelligence Development Studio 的 [變數] 視窗中,建立具有字串資料類型的變數,以保存「執行 SQL」工作所傳回的查詢字串。

    這個範例會使用變數名稱 SqlDataQuery。

建立封裝變數後,您可以使用「指令碼」工作或「執行 SQL」工作來串連輸入參數的值。下列兩個程序描述如何設定這些元件。

使用指令碼工作串連查詢字串

  1. [控制流程] 索引標籤上,將「指令碼」工作加入到「For 迴圈」容器後的封裝中,然後將「For 迴圈」容器連接到該工作。

    [!附註]

    此程序假設封裝會從單一資料表執行累加式載入。如果封裝從多個資料表載入,而且擁有包含多個子封裝的父封裝,則會將此工作當做第一個元件,加入到每個子封裝中。如需詳細資訊,請參閱<執行多個資料表的累加式載入>。

  2. [指令碼工作編輯器][指令碼] 頁面上,選取下列選項:

    1. 針對 [ReadOnlyVariables],選取 [User::DataReady][User::ExtractStartTime][User::ExtractEndTime]

    2. 針對 [ReadWriteVariables],從清單中選取 [User::SqlDataQuery]。

  3. [指令碼工作編輯器][指令碼] 頁面上,按一下 [編輯指令碼] 來開啟指令碼開發環境。

  4. 在 Main 程序中,輸入下列其中一個程式碼區段:

    • 如果您是以 C# 撰寫程式,輸入下列程式碼行:

          int dataReady;
          System.DateTime extractStartTime;
          System.DateTime extractEndTime;
          string sqlDataQuery;
      
          dataReady = (int)Dts.Variables["DataReady"].Value;
          extractStartTime = (System.DateTime)Dts.Variables["ExtractStartTime"].Value;
          extractEndTime = (System.DateTime)Dts.Variables["ExtractEndTime"].Value;
      
          if (dataReady == 2)
            {
            sqlDataQuery = "SELECT * FROM CDCSample.uf_Customer('" + string.Format("{0:yyyy-MM-dd hh:mm:ss}", extractStartTime) + "', '" + string.Format("{0:yyyy-MM-dd hh:mm:ss}", extractEndTime) + "')";
            }
          else
            {
            sqlDataQuery = "SELECT * FROM CDCSample.uf_Customer(null" + ", '" + string.Format("{0:yyyy-MM-dd hh:mm:ss}", extractEndTime) + "')";
            }
      
          Dts.Variables["SqlDataQuery"].Value = sqlDataQuery;
      

      -或-

    • 如果您是以 Visual Basic 撰寫程式,輸入下列程式碼行:

          Dim dataReady As Integer
          Dim extractStartTime As Date
          Dim extractEndTime As Date
          Dim sqlDataQuery As String
      
          dataReady = CType(Dts.Variables("DataReady").Value, Integer)
          extractStartTime = CType(Dts.Variables("ExtractStartTime").Value, Date)
          extractEndTime = CType(Dts.Variables("ExtractEndTime").Value, Date)
      
          If dataReady = 2 Then
            sqlDataQuery = "SELECT * FROM CDCSample.uf_Customer('" & _
                String.Format("{0:yyyy-MM-dd hh:mm:ss}", extractStartTime) & _
                "', '" & _
                String.Format("{0:yyyy-MM-dd hh:mm:ss}", extractEndTime) & _
                "')"
          Else
            sqlDataQuery = "SELECT * FROM CDCSample.uf_Customer(null" & _
                ", '" & _
                String.Format("{0:yyyy-MM-dd hh:mm:ss}", extractEndTime) & _
                "')"
          End If
      
          Dts.Variables("SqlDataQuery").Value = sqlDataQuery
      
  5. 保留從指令碼之執行傳回 DtsExecResult.Success 的預設程式碼行。

  6. 關閉指令碼開發環境以及 [指令碼工作編輯器]

使用執行 SQL 工作串連查詢字串

  1. [控制流程] 索引標籤上,將「執行 SQL」工作加入到「For 迴圈」容器後的封裝中,然後將「For 迴圈」容器連接到該工作。

    [!附註]

    此程序假設封裝會從單一資料表執行累加式載入。如果封裝從多個資料表載入,而且擁有包含多個子封裝的父封裝,則會將此工作當做第一個元件,加入到每個子封裝中。如需詳細資訊,請參閱<執行多個資料表的累加式載入>。

  2. [執行 SQL 工作編輯器][一般] 頁面上,選取下列選項:

    1. 針對 [ResultSet],選取 [單一資料列]

    2. 將有效的連接設定到來源資料庫。

    3. 針對 [SQLSourceType],選取 [直接輸入]

    4. 針對 [SQLStatement],輸入下列 SQL 陳述式:

      declare @ExtractStartTime datetime,
      @ExtractEndTime datetime, 
      @DataReady int
      
      select @DataReady = ?, 
      @ExtractStartTime = ?, 
      @ExtractEndTime = ?
      
      if @DataReady = 2
      select N'select * from CDCSample.uf_Customer'
      + N'('''+ convert(nvarchar(30),@ExtractStartTime,120)
      + ''', '''
      + convert(nvarchar(30),@ExtractEndTime,120) + ''') ' 
      as SqlDataQuery
      else
      select N'select * from CDCSample.uf_Customer'
      + N'(null, '''
      + convert(nvarchar(30),@ExtractEndTime,120)
      + ''') '
      as SqlDataQuery
      

      [!附註]

      此範例中的 else 子句會傳遞開始日期和時間的 null 值,藉以產生變更資料之初始載入的查詢。此範例不處理啟用異動資料擷取前所進行之變更也必須上傳到資料倉儲的狀況。

  3. [執行 SQL 工作編輯器][參數對應] 頁面上,進行下列對應:

    1. 將 DataReady 變數對應到參數 0。

    2. 將 ExtractStartTime 變數對應到參數 1。

    3. 將 ExtractEndTime 變數對應到參數 2。

  4. [執行 SQL 工作編輯器][結果集] 頁面上,將 [結果名稱] 對應到 SqlDataQuery 變數。

    [結果名稱] 是所傳回之單一資料行的名稱,也就是 SqlDataQuery。

上一個程序會利用輸入參數的硬式編碼字串值,設定可準備查詢字串的工作。下列程式碼為此種查詢字串的範例:

select * from CDCSample. uf_Customer('2007-06-11 14:21:58', '2007-06-12 14:21:58')

加入資料流程工作

設計封裝之控制流程的最後一個步驟是加入「資料流程」工作。

加入資料流程工作並完成控制流程

  • [控制流程] 索引標籤上,加入「資料流程」工作,然後連接串連查詢字串的工作。

下一個步驟

準備查詢字串並設定「資料流程」工作後,下一個步驟是建立將從資料庫擷取變更資料的資料表值函式。

下一個主題:建立函數以擷取變更資料

Integration Services 圖示 (小) 掌握 Integration Services 的最新狀態

若要取得 Microsoft 的最新下載、文件、範例和影片以及社群中的選定解決方案,請瀏覽 MSDN 或 TechNet 上的 Integration Services 頁面:

若要得到這些更新的自動通知,請訂閱該頁面上所提供的 RSS 摘要。