Execute SQL Task 第三篇:參數和變量的映射


Execute SQL Task 第一篇:用法簡介

Execute SQL Task 第二篇:返回結果集

Execute SQL Task 第三篇:參數和變量的映射

 

 

Execute SQL Task能夠執行帶參數的SQL查詢語句或存儲過程(SP),通過SSIS的變量(Variable)對參數賦值。對於不同的Connection Manager,在Task中需要使用不同的符號(Parameter marker)來標記一個參數,並且在Parameter Mapping中設置參數名字(Parameter Name)。

在Execute SQL Task Editor中,設置Parameter Mapping的界面如下:

  • Variable Name:變量的名字,變量的作用域分為UserSystem,使用 :: 來引用作用域中的變量
  • Direction:參數的方向,分為輸入參數(Input),輸出參數(Output)和返回值(Returnvalue)
  • Data Type:參數的Data Type,必須和變量(Variable)的數據類型相兼容
  • Parameter Name:參數名字,不同的Connection Manager,其值不同,對於OLEDB Connection Manager,使用0,1,2等數值表示第一個,第二個參數,第三個參數等。
  • Parameter Size:默認值是-1,表示讓SSIS確定參數的長度。如果參數的數據類型是變長的(varchar或varbinary),必須設置參數的長度,為參數值分配足夠長度的空間。

在Parameter Mapping中,Parameter Marker和Name受到Connection Type的影響,如下表:

Connection type Parameter marker Parameter name Example SQL command
ADO ? Param1, Param2, … SELECT FirstName, LastName, Title FROM Person.Contact WHERE ContactID = ?
ADO.NET @<parameter name> @<parameter name> SELECT FirstName, LastName, Title FROM Person.Contact WHERE ContactID = @parmContactID
ODBC ? 1, 2, 3, … SELECT FirstName, LastName, Title FROM Person.Contact WHERE ContactID = ?
EXCEL and OLE DB ? 0, 1, 2, 3, … SELECT FirstName, LastName, Title FROM Person.Contact WHERE ContactID = ?

1,執行SQL查詢語句

樓主在實際開發中,最常用的Connection Type是OLEDB,設置Task的ConnectionType為OLE DB,在SQLStatement屬性中使用 ? 來標記一個參數,? 叫做參數標記(Parameter Marker)。

select ID,c1
from dbo.dt_test
where c1=?

使用SSIS 變量(Variable)為參數賦值,Parameter Name必須是0,1,2等數字

2,執行SP,設置參數的方向

使用Execute SQL Task執行SP時,參數映射的Direction屬性使用Input,Output和Returnvalue 分別表示:輸入參數,輸出參數和SP的返回值

declare @return_value int 
declare @output_var int 
declare @input_var int
set @input_var=1
exec @return_value=dbo.usp_test @para1=@input_var, @para2= @output_var output;

使用OLEDB Connection Manager,使用 ? 表示一個參數,如圖

在Parameter Mapping Tab中設置參數映射:

  • 第一個參數是SP的返回值,Direction 選擇 Returnvalue,Parameter Name 是 0;
  • 第二個參數是SP的輸入參數,Direction 選擇 Input,Parameter Name 是 1;
  • 第三個參數是SP的輸出參數,Direction 選擇 Output,Parameter Name 是 2;

 

3,設置參數的Data Type

樓主整理的參數的Data Type和TSQL 數據類型的映射關系

3.1,數值類型

  • BYTE:映射 SSIS 的 DBTYPE_UI1,映射 TSQL 的 TinyInt
  • SHORT:映射 SSIS 的 DBTYPE_I2, 映射 TSQL 的 smallint
  • LONG:映射 SSIS 的 DBType_I8,映射 TSQL 的 bigint
  • FLOAT: 映射 TSQL 的 float(24)
  • DOUBLE:映射 TSQL 的 float(53)
  • DECIMAL: 映射 TSQL 的 decimal

3.2,日期/時間類型

  • DATE:映射TSQL的DateTime2(7)
  • DBDATE:映射TSQL的Date
  • DBTIME:映射TSQL的time(2)
  • DBTIME2:映射TSQL的time(7)
  • DBTIMESTAMP:映射TSQL的Datetime
  • FILETIME:映射TSQL的datetime

注意:如果SSIS 變量的Data Type是DateTime,那么參數的Data Type應使用 DATE,但是,數據類型為DateTime的變量,只保留到秒,毫秒位是0.

 

3.3,字符串類型

  • VARCHAR: 映射TSQL的varchar
  • NVARCHAR: 映射TSQL的nvarchar

4,在做增量更新時,發現導入的數據量少於源數據

樓主在調試SSIS Package時,使用ModifiedDate字段做增量更新,Package中使用Execute SQL Task獲取數據源中DataUpdateTime字段的最大值,並將該值賦值給變量:User::MaxLastModifiedDate,Package運行成功,但是導入的數據量少於源數據;通過測試,發現DateTime類型的變量,其時間部分只保留到秒,而不會計算毫秒部分,導致導入的數據量少於源數據。

調試SSIS Package,下斷點(breakpoint),打開Watch Tab,查看變量運行時的值:

這兩個變量定義為DateTime類型,經過測試,如果變量定義成String類型,實際上是一樣的,時間只會精確到秒:

然而,數據源中的DataUpdateTime使用的Datetime2(7),精度十分高:

發生這種問題的根源是 SSIS的數據類型和SQL Server的數據類型不是一一對應的,存在差異。為了避免這種問題,可以對MaxLastModifiedDate 變量加1s。

在使用OLEDB數據源導入數據時,使用如下的Where條件,就能把所有的數據都導入到DW中。

where DataUpdatedOn > ?    --MinLastModifiedDate
and DataUpdatedOn<=?        --MaxLastModifiedDate

注意:SSIS 變量的日期和時間類型只保留到秒,而數據庫中的時間可以保留到毫秒位(1-7位毫秒數)

 

參考文檔:

SQL Server SP2 – What’s new for SSIS

Map Query Parameters to Variables in an Execute SQL Task

Parameters and Return Codes in the Execute SQL Task


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM