因儲存過程引數型別不匹配而造成OleDbCommand的不可用(二) (轉)
(續 /develop/read_article.?id=18426">因過程引數型別不匹配而造成OleCommand的不可用一)
表格二,斷點二處的狀況
-:namespace prefix = o ns = "urn:schemas--com::office" />
comm
{System.Data.OleDb.OleDbCommand}
System.Data.OleDb.OleDbCommand
transaction
null
System.Data.OleDb.OleDbTransaction
cmdText
Test
string
cmdType
StoredProcedure
System.Data.CommandType
updatedRow
Both
System.Data.UpdateRowSource
commandTimeout
30
int
+
icommandText
{System.__Com}
System.Data.Common.UnsafeNativeMethods.ICommandText
handle_Accessor
1
int
commandBehavior
Default
System.Data.CommandBehavior
+
dbBindings
{System.Data.OleDb.DBBindings}
System.Data.OleDb.DBBindings
canceling
FALSE
bool
isPrepared
FALSE
bool
executeQuery
FALSE
bool
computedParameters
FALSE
bool
designTimeVisible
FALSE
bool
cmdState
0
int
recordsAffected
-1
int
CommandText
Test
string
CommandTimeout
30
int
CommandType
StoredProcedure
System.Data.CommandType
DesignTimeVisible
TRUE
bool
IsClosed
TRUE
bool
Transaction
null
System.Data.OleDb.OleDbTransaction
UpdatedRowSource
Both
System.Data.UpdateRowSource
由上面表格一和表格二可發現,在OleDbCommand第一次ExecuteNoQuery()時,將改變其內部icommandText,dbBindings,handle_Accessor等3個私有屬性。並且經過觀察發現,只有CommandText被賦予與原來不同的值時才把以上3個私有屬性的值恢復到原來的預設值(即icommandText=null,dbBindings=null,handle_Accessor=0)。
這時我們把上面的程式碼稍作修改,在第一個try塊裡給原本為儲存過程引數Age賦與一個不能轉換為整數值的字串:
using System;
using System.Data;
using System.Data.OleDb;
namespace testCommand
{
class Class1
{
[STAThread]
static void
{
OleDbConnection conn=new OleDbConnection("xxx");
conn.Open();
OleDbCommand comm=new OleDbCommand("Test",conn);
comm.CommandType=CommandType.StoredProcedure;
OleDbCommandBuilder.DeriveParameters(comm);
try
{
comm.Parameters["Name"].Value="my name";
comm.Parameters["Age"].Value=(object)”aa”;
comm.ExecuteNonQuery(); //斷點三,此處記憶體狀況見表一
}
catch(Exception err)
{
Console.WriteLine(
err.TargetSite+" -- "+err.StackTrace+" -- "+
err.Source+" -- "+err.Message+" -- "+
err.GetType().ToString());
}
//TODO: 增加對OleDbCommand進行修復的語句
try
{
comm.Parameters["Name"].Value="my name";
comm.Parameters["Age"].Value=(object)11;
comm.ExecuteNonQuery(); //斷點四
}
catch(Exception err)
{
Console.WriteLine(
err.TargetSite+" -- "+err.StackTrace+" -- "+
err.Source+" -- "+err.Message+" -- "+
err.GetType().ToString());
}
conn.Close();
}
}
}
這時,在執行到斷點三時會丟擲System.FormatException的例外,再觀察斷點四處的記憶體狀況:
+
icommandText
{System.__ComObject}
System.Data.Common.UnsafeNativeMethods.ICommandText
handle_Accessor
0
int
dbBindings
null
System.Data.OleDb.DBBindings
CommandText
Test
string
CommandType
StoredProcedure
System.Data.CommandType
發現icommandText,dbBindings,handle_Accessor三個私有屬性只有icommandText被修改。程式在往下執行,我們得到System.Data.OleDb.OleDbException例外,提示Command text was not set for the command object。但是此時的CommandText及CommandType都為有效值。可見ExecuteNoQuery()在執行命令時依賴於icommandText,dbBindings和handle_Accessor。而之前的第一個try塊,由於儲存過程引數型別的不匹配丟擲異常,使ExecuteNoQuery()執行和只有icommandText一個私有屬性發生改變,此時雖然CommandText和CommandType還是原來正確的值,但由於dbBindings和handle_Accessor 沒有被正確賦值而丟擲認為沒有命令文字的例外。
於是我們可以假設OleDbCommand在執行時是判斷icommandText屬性是否為空值再根據命令文字生成私有屬性的時候,如果是則分析CommandText的值修改icommandText,dbBindings,handle_Accessor等3個私有屬性;否則直接時用icommandText,dbBindings,handle_Accessor已有的值。如果CommandText的值發生改變,OleDbCommand重設icommandText,dbBindings,handle_Accessor的值,在下一次執行ExecuteNoQuery() 時根據命令文字重新生成私有屬性的值。
這樣,由儲存過程引數不匹配而引起的OleDbCommand不可用的問題就迎刃而解了。只需要在兩個try塊間的加入以下語句 即可:
comm.CommandText=””;
comm.CommandText=”Test”;
以上對於OleDbCommand的討論居於.Net 1.0來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-956641/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 因儲存過程引數型別不匹配而造成OleDbCommand的不可用(一) (轉)儲存過程型別
- 儲存過程輸入引數型別定義引起的問題儲存過程型別
- mysql儲存過程的引數MySql儲存過程
- 詳解MySQL儲存過程引數有三種型別(in、out、inout)MySql儲存過程型別
- 帶輸出引數的儲存過程儲存過程
- oracle父儲存過程呼叫子儲存過程procedure與輸出引數Oracle儲存過程
- 動態呼叫帶引數的儲存過程儲存過程
- 使用帶有輸出引數的儲存過程儲存過程
- 從sybase的儲存過程轉向oracle的儲存過程儲存過程Oracle
- MySQL 儲存過程引數IN OUT INOUT對比MySql儲存過程
- Java呼叫儲存過程(帶輸出引數)Java儲存過程
- oracle儲存過程將引數字串分割sqlOracle儲存過程字串SQL
- Oracle帶輸入輸出引數的儲存過程Oracle儲存過程
- SQLSERVER儲存過程如何寫帶引數的遊標SQLServer儲存過程
- dos下呼叫帶輸出引數的儲存過程儲存過程
- 造數儲存過程儲存過程
- oracle procedure儲存過程輸入引數用於sql like模糊匹配2演算法Oracle儲存過程SQL演算法
- SQL Server-儲存過程(Procedure),帶入引數和出引數SQLServer儲存過程
- 儲存過程的引數可以使用sql的函式儲存過程SQL函式
- SQL Server系統儲存過程和引數示例SQLServer儲存過程
- jdbctemplate呼叫儲存過程傳遞陣列引數JDBC儲存過程陣列
- JAVA儲存過程(轉)Java儲存過程
- 儲存過程中巢狀儲存過程的變數執行方式儲存過程巢狀變數
- MySQL 中 整數型別的儲存和範圍計算過程詳解MySql型別
- go 如何呼叫 sqlserver 帶傳出引數的儲存過程GoSQLServer儲存過程
- bbs的資料結構和儲存過程(二) (轉)資料結構儲存過程
- MySQL儲存過程in、out、inout引數示例與總結MySql儲存過程
- SQL Server系統儲存過程和引數總結SQLServer儲存過程
- 過程需要型別為 'ntext/nchar/nvarchar' 的引數 '@statement'型別
- 儲存過程單引號問題儲存過程
- 簡單的造數儲存過程儲存過程
- 在不破壞原加密儲存過程的前提下,解密儲存過程!(補充j9988) (轉)加密儲存過程解密
- 儲存過程WHERE條件不生效儲存過程
- SQL分隔字串的儲存過程 (轉)SQL字串儲存過程
- 求助:DB2 V7儲存過程引數限制DB2儲存過程
- 儲存過程和函式的區別儲存過程函式
- Oracle基本資料型別儲存格式淺析(二)——數字型別Oracle資料型別
- MySQL儲存過程詳解 mysql 儲存過程MySql儲存過程