淺談Parameters.AddWithValue的自動型別判斷

很多人吃了不少Parameters.AddWithValue的虧,因為它帶的型別與我們預料的不同,所以導致後續的問題,進而放棄使用 AddWithValue,改用給予明確型別的的方式,究竟Parameters.AddWithValue是怎麼去判斷帶入的值要用什麼型別?

很多人吃了不少Parameters.AddWithValue的虧,因為它帶的型別與我們預料的不同,所以導致後續的問題,進而放棄使用AddWithValue,改用給予明確型別的的方式,究竟Parameters.AddWithValue是怎麼去判斷帶入的值要用什麼型別?

從先前那篇[ Parameter參數中的DBType重要性 ] 就知道錯誤的型別還會影響到效能,因為不瞭解Parameters.AddWithValue自動型別判斷的方式,反而不太敢用它,為了瞭解這點,所以這邊用一個很簡單的方式來驗證Parameters.AddWithValue的型別判斷方式.

 

先來看Oracle的部份.

建立一個OracleConnection conn=new …..及OracleCommand cmd=conn.CreateCommand();

再來宣告幾種不同的變數,並用AddWithValue的方式,把它加進去.

string str="ABCDEFG";

DateTime dtTime = DateTime.Now;

UInt64 u64= 1234;

int i = 1234;

cmd.Parameters.AddWithValue("str", str);

cmd.Parameters.AddWithValue("dtTime", dtTime);

cmd.Parameters.AddWithValue("num1", u64);

cmd.Parameters.AddWithValue("num2", i);

 

接下來就可以看到它的DbType及OraleType變成什麼,還有Size有什麼樣的變化.

str : DbType=AnsiString ; OracleType=VarChar ; size=7

dtTime : DbType=DateTime ; OracleType=DateTime ; size=0

num1 : DbType=UInt64 ; OracleType=Number ; size=0

num2 : DbType=Int32 ; OracleType=Int32 ; size=0

 

用同樣的方式,把它改為SQL來看看有什麼不同.

結果在取得Parameter的DbType及SqlDbType時丟回Exception :

UInt64 的參數資料型別無效。

那把Uint64改為int64再來試一次.結果如下

str : DbType=String ; SqlDbType=NVarChar ; size=7

dtTime : DbType=DateTime ; SqlDbType=DateTime ; size=0

num1 : DbType=Int64 ; SqlDbType=BigInt ; size=0

num2 : DbType=Int32 ; SqlDbType=Int ; size=0

 

看來它是依我們丟進去的Object型別及使用的DB種類(SqlCommand or OracleCommand ….etc/)來判斷,而size部份,則是看type與value.

 

而UInt64為什麼會出現Exception,這個可以從以下提供的對應表中看到答案.

Inferring a SqlDbType from UInt64 is not supported. 

 

以下有幾個MSDN提供的對應表 :

Mapping Data Types

SQL Server Data Type Mappings (ADO.NET)

Working with Command Parameters