2012-04-27 71 views
4
sqlQuery = "SELECT [ID] from [users] WHERE [email protected]"; 

OleDbConnection conn = new OleDbConnection(connectionString); 
conn.Open(); 
cmd = new OleDbCommand(sqlQuery, conn); 
cmd.CommandText = sqlQuery; 
cmd.Parameters.Add("@CallerName", OleDbType.VarChar).Value = labelProblemDate.Text.Trim(); 
cmd.Parameters["@CallerName"].Value = name; 
cmd.ExecuteNonQuery();   
conn.Close(); 

我被告知這是如何使用參數從SELECT查詢中讀取數據,但它不起作用。我想我做錯了什麼。來自OleDbCommand的返回值

我使用的WinForms和Microsoft Access 2007

+0

你收到了哪些錯誤信息?另外,你似乎混淆了你的'@ CallerName'參數。什麼是變量「名稱」,並且「ExecuteNonQuery」將不會執行選擇。 – Ste 2012-04-27 16:36:40

+1

你想要所有的ID都有這個名字嗎?如果後者最好'SELECT TOP 1 ID FROM [users] WHERE CallerName = @ CallerName'。然後使用['ExecuteScalar'](http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbcommand.executescalar.aspx)(內部鏈接)檢索只有一個選定的ID(如果有的話) )。 – 2012-04-27 16:40:52

回答

5

看起來你有你的答案,但我想從您的示例代碼,指出幾件事情:

sqlQuery = "SELECT [ID] from [users] WHERE [email protected]"; 

OleDbConnection conn = new OleDbConnection(connectionString); 
conn.Open(); 
cmd = new OleDbCommand(sqlQuery, conn); 
cmd.CommandText = sqlQuery; 
cmd.Parameters.Add("@CallerName", OleDbType.VarChar).Value = labelProblemDate.Text.Trim(); 
cmd.Parameters["@CallerName"].Value = name; 
cmd.ExecuteNonQuery(); 
conn.Close(); 

首先,請注意你的SQL查詢使用Microsoft SQL語法,並且Microsoft Access更喜歡稍微不同的語法。相反,包裹在方括號中列名的,使用波浪號:

sqlQuery = "SELECT `ID` from `users` WHERE `CallerName`[email protected]"; 

接下來,在你的SQL查詢,請注意,Microsoft Access不接受命名參數。你的SQL文本上面使用@CallerName將沒有問題執行,但所有的OleDb對象將看到的是這樣的:

sqlQuery = "SELECT `ID` from `users` WHERE `CallerName`=?"; 

如果在某一點後,你決定去與存儲過程而不是文字SQL,記得在添加參數和執行命令之前,在OleDbCommand上調用Prepare()

如果您有多個參數,請確保按照您在SQL文本中調用它們的順序將這些參數添加到OleDbCommand。 OleDb並不在乎你的名字,但你可以自己使用它們來幫助你;它不在查詢中使用。 @CallerName將不會嘗試與您的SQL文本中的任何內容匹配。

接下來,我想看看您使用OleDbParameter項目。在下面的兩行中,您將爲OleDbCommand添加一個(1)參數,其值爲labelProblemDate.Text.Trim()並且在下一行中您將重新指定爲將同一參數值重新分配給變量(這對我們來說是未知的)稱爲name。如果用一個值聲明該參數,然後將其重新分配給其他值,那沒有用。

您也可以使用以下修改的摘錄,並得到了相同的結果(記得要加的大小字段,如下圖所示,在數據庫中指定):

cmd.Parameters.Add("@CallerName", OleDbType.VarChar, 255).Value = labelProblemDate.Text.Trim(); 
// cmd.Parameters["@CallerName"].Value = name; 

同樣,你OleDbCommand正在與創建您sqlQuery參數,因此指定你的命令的CommandText屬性是不必要的:

cmd = new OleDbCommand(sqlQuery, conn); 
//cmd.CommandText = sqlQuery; 

最後,正如其他人所說,如果你想查詢你的數據,你的SQL語句建議,你必須讀取數據,而不是調用ExecuteNonQuery()(請注意,它被稱爲非查詢)。

概括起來講,我寫出來的位置:

sqlQuery = "SELECT `ID` from `users` WHERE `CallerName`=?"; 
int result = 0; 
OleDbConnection conn = new OleDbConnection(connectionString); 
try { 
    conn.Open(); 
    var cmd = new OleDbCommand(sqlQuery, conn); 
    //cmd.CommandText = sqlQuery; This command was specified by your initializer 
    cmd.Parameters.Add("?", OleDbType.VarChar, 255).Value = labelProblemDate.Text.Trim(); 
    //cmd.Parameters["@CallerName"].Value = name; Possible bug here 
    using (OleDbDataReader reader = cmd.ExecuteReader()) 
    { 
    if(reader.HasRows) 
    { 
     reader.Read(); 
     result = reader.GetInt32(0); 
    } 
    } 
} finally { 
    conn.Close(); 
} 
return result; 

始終把情況在finally塊的關閉程序拋出一個錯誤的任何理由。這可以防止應用程序崩潰並使文件保持打開狀態。我發現,一個using條款在完成時並不一定會關閉連接(就像它們應該這樣做)。

我希望這會有所幫助。我現在刷新了我對OleDb的瞭解,並想指出一些事情。

+0

我認爲使用語句應該做關閉連接的工作......在什麼情況下他們不這樣做? – TulkinRB 2017-04-26 14:40:25

+0

這就是*使用語句*應該做的事情。我不確定Access爲什麼沒有。只是猜測,我會說這是因爲Access數據庫通常是本地的,在用戶的PC上,Access組決定在程序啓動並運行時沒有理由關閉它們的數據庫。 – jp2code 2017-04-26 14:43:20

+0

你在談論連接池嗎?如果你這樣做實際上是一個好主意,因爲你沒有打開連接的開銷,並且可以將「關閉」連接視爲有效關閉(服務器關閉後,ASP將關閉它們)。我認爲它可以像finally-connection.close()一樣工作 – TulkinRB 2017-04-26 19:02:36

2

如果查詢返回一個值,你可以使用ExecuteScalar檢索值。 ExecuteNonQuery不會從您的數據庫返回值;相反,它旨在與UPDATE語句等一起使用,並返回受該語句影響的行數。

您可能知道這一點,但通常情況下,SELECT查詢可以返回多個行(和多個列),因此要「從SELECT查詢中讀取數據」,可以使用ExecuteReader來獲得DbDataReader

6

ExecuteNonQuery不返回數據,僅受您的命令
您需要使用的ExecuteReader與OleDbDataReader

OleDbDataReader reader = cmd.ExecuteReader();   
if(reader.HasRows) 
{ 
    reader.Read(); 
    var result = reader.GetInt32(0); 
} 
1

讀取數據並將其加載到數據表中的行:

OleDataReader rdr = (OleDataReader) cmd.ExecuteReader(); 
DataTable dt = new DataTable(); 
dt.Load(rdr); 

讀取Scalor數值數據並將其加載到變量中:

int result = (int)cmd.ExecuteScalar(); //Assume scalar value to be return is int 

我希望它能幫助