2015-09-10 108 views
4

切換爲使用SQL Native Client(SQLNCLI)作爲ADO提供程序時,我們的舊應用程序遇到了問題。SQL本機客戶端數據類型兼容性 - 與SQLOLEDB不兼容

我們原來的連接字符串是:

Provider=SQLOLEDB; Server=host; Database=bob; Integrated Security=SSPI; 

我們把它改爲:

Provider=SQLNCLI11; Server=host; Database=bob; Integrated Security=SSPI; DataTypeCompatibility=80; 

我們發現的是,調用存儲過程時,使用adDBTimeStamp的參數,本機客戶端似乎將時間戳記視爲smalldatetime,而不是日期時間。由於我們在某些比較中將9999年12月31日用作「最高端」日期,因此導致我們遇到問題,並且Native Client在SQLOLEDB沒有問題的情況下失敗,出現「無效日期格式」錯誤。

現在看起來我們可能只是可以從adDBTimeStamp更改爲adDate作爲創建參數時的數據類型,但是我想知道是否有一些我們在連接字符串中丟失之前,我們繼續前進,並使代碼更改。

下面重現的VBScript代碼。爲了避免疑問,在有人建議我們應該使用12/31/9999之前,日期格式爲英國(dd/mm/yyyy):但是也要確認,CDate不會失敗。

Set db = CreateObject("ADODB.Command") 

' If Provider=SQLOLEDB then there is no error. 
db.ActiveConnection = "Provider=SQLNCLI11; Server=host; Database=bob; Integrated Security=SSPI; DataTypeCompatibility=80;" 
db.CommandText = "usp_FetchData" 
db.CommandType = &H0004 

' 135 is adDBTimeStamp 
db.Parameters.Append db.CreateParameter("@screenDate", 135, 1, 20, CDate("31/12/9999")) 

Set rs = CreateOBject("ADODB.RecordSet") 
' Then this line fails with "Invalid date format" from SQLNCLI 
rs.Open db 

WScript.Echo rs.RecordCount 

纏繞日期時間回到2078(SMALLDATETIME的日期範圍內),使錯誤消失。

如前所述,如果可以找到非代碼更改修復程序,那麼我們就更喜歡,在我們開始之前必須將adDBTimeStamp更改爲adDate。我期望DataTypeCompatiblity = 80的行爲像SQLOLEDB;不幸的是,當我找到SQLNCLI使用的映射類型時,我的Google-fu失敗了。

回答

0

的溶液可能已經最終已發現:通過的MSDN頁,有這種片斷朝向端:

數據類型映射在ITableDefinition :: CREATETABLE

以下類型映射使用具有DBCOLUMNDESC結構使用 通過ITableDefinition :: CREATETABLE:

[...轉換表...]

當應用程序在wType中指定DBTYPE_DBTIMESTAMP時,通過在 pwszTypeName中提供類型名稱,它可以 覆蓋到datetime2的映射。 如果指定的日期時間,bScale必須3.如果指定 SMALLDATETIME時,bScale必須是0如果bScale不 與和WTYPE一致pwszTypeName,返回DB_E_BADSCALE。

在測試中,似乎需要設置縮放比例適用於SELECT和命令的參數以及CreateTable。因此,如果我們將上面的腳本更改爲:

Set param = db.CreateParameter("@screenDate", 135, 1, 20, CDate("31/12/9999")) 
param.NumericScale = 3 
db.Parameters.Append param 

...然後錯誤消失並執行存儲過程。我們正處於測試的早期階段,但是如果這引發了問題,歡迎來自其他人的反饋。