6

ADO のプロバイダーとして SQL Native Client (SQLNCLI) を使用するように切り替えたときに、従来のアプリケーションで問題が発生しました。

元の接続文字列は次のとおりです。

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

これを次のように変更しました。

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

私たちが発見したことは、adDBTimeStamp のパラメーターを使用してストアド プロシージャを呼び出すと、Native Client はタイムスタンプを datetime ではなく smalldatetime として扱うように見えるということです。一部の比較で 9999 年 12 月 31 日を「最上位」の日付として使用し、SQLOLEDB には問題がなかったのに「無効な日付形式」エラーでネイティブ クライアントが失敗するため、これが問題を引き起こしています。

これで、パラメーターを作成するときにデータ型を adDBTimeStamp から adDate に変更できるように見えますが、先に進んでコードを変更する前に、接続文字列に欠けているものがあるのではないかと考えていました。

以下に再現するVBScriptコード。誤解を避けるために、日付形式は UK (dd/mm/yyyy) であり、誰かが 12/31/9999 を使用する必要があると提案する前に :-) 確認するために、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

datetime を (smalldatetime の日付範囲内で) 2078 に戻すと、エラーが解消されます。

前述のように、コードを変更しない修正が見つかった場合は、adDBTimeStamp を adDate に変更する前に、それが望ましいことです。DataTypeCompatiblity=80 が SQLOLEDB として動作することを期待していました。残念ながら、私の Google-fu は、SQLNCLI が使用する型マッピングを正確に見つけるときに失敗しました。

4

1 に答える 1