2014-11-21 32 views
3

首先,我想感謝任何閱讀此內容和回答的人。非常感謝您的幫助!如何從調用存儲過程中正確捕獲返回值

我一直在開發一個ASP.NET Web應用程序,我需要讀取和寫入數據庫。爲此,我一直試圖從我的C#代碼中調用一些我編寫的存儲過程。特別是這一個:

public static bool userExistsInDB(string username) 
{ 
    int userExistsInDB = -1; 
    using (SqlConnection con = new SqlConnection(DBConfig.DbConnectString)) 
    { 
     using (SqlCommand cmd = new SqlCommand("tb_user_exists", con)) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add("@username", SqlDbType.VarChar).Value = username; 
      con.Open(); 
      userExistsInDB = cmd.ExecuteNonQuery(); 
     } 
    } 
    return userExistsInDB == 1; 
} 

存儲過程調用我用這個SQL腳本創建:

CREATE PROCEDURE tb_is_logged_in 
    @username VARCHAR(20) 
AS 
IF(EXISTS(SELECT * FROM logged_in_users WHERE "username" = @username)) 
BEGIN 
    RETURN 1; 
END 
ELSE 
BEGIN 
    RETURN 0; 
END 

我測試了它自身在SQL Server Management Studio中,它似乎工作。然而,在通過我的C#代碼踩着我找到行

userExistsInDB = cmd.ExecuteNonQuery(); 

存儲過程應該指定的用戶在數據庫中分別存在與否,返回1或0的一個問題,正如你可以看到userExistsInDB-1初始化。但是,在執行userExistsInDB = cmd.ExecuteNonQuery();行之後userExistsInDB從不被修改;它始終保留價值-1。所以看來我得到錯誤的返回值。我究竟做錯了什麼?

編輯:

感謝萊昂內爾,我找到了一個解決問題的辦法。首先,我意識到我上面粘貼的存儲過程不是正確的過程。這不是我實際上在我的C#代碼中調用的那個,當我嘗試Leonel的修復時,它不起作用,因爲我不小心編輯了上面粘貼的過程而不是實際調用的過程。下面是實際的存儲過程我打電話:

CREATE PROCEDURE tb_user_exists 
    @username VARCHAR(20) 
AS 
IF(EXISTS (SELECT * FROM users WHERE username = @username)) 
BEGIN 
    RETURN 1; 
END 
ELSE 
BEGIN 
    RETURN 0; 
END 

我的解決方案如下:改變這一行

userExistsInDB = cmd.ExecuteNonQuery(); 

userExistsInDB = (int)cmd.ExecuteScalar(); 

,改變存儲過程:

CREATE PROCEDURE tb_user_exists 
    @username VARCHAR(20) 
AS 
IF(EXISTS (SELECT * FROM users WHERE username = @username)) 
BEGIN 
    SELECT 1; 
END 
ELSE 
BEGIN 
    SELECT 0; 
END 
+0

代碼總是讀比它的屏幕截圖更好後關閉的連接。粘貼實際的源代碼,我會幫助正確格式化。 – abatishchev 2014-11-21 04:13:16

+0

好的,謝謝! – Tom 2014-11-21 04:14:26

+0

你用ExecuteScalar試試嗎?這裏是ExecuteScalar和ExecuteNonQuery的區別的簡要說明http://stackoverflow.com/questions/2974154/what-is-the-difference-between-executescalar-executereader-and-executenonquery – bsting 2014-11-21 04:16:26

回答

1

使用SqlCommand.ExecuteScalar();方法從MSDN

例如:

userExistsInDB = (int)cmd.ExecuteScalar(); 

示例代碼將執行SqlCommand和檢索表,如果第一行存在並將該變量的值設置爲表中的項目數。在這種情況下,你可以刪除return語句,並使用

SELECT * FROM logged_in_users WHERE "username" = @username 

而且還總是用它

con.Open(); 
userExistsInDB = cmd.ExecuteScalar(); 
con.Close(); 
+0

謝謝,我會嘗試。另外:當塊完成時,不會在'using'塊中聲明'SqlConnection'對象來關閉連接。或者是明確關閉連接只是更好的做法? – Tom 2014-11-21 05:03:33

+0

@Tom最好的做法是在執行後關閉連接。 – 2014-11-21 05:05:55

+0

我嘗試了你說的並且遇到了這個異常:在TaskBlasterDBAccessObjects.dll中發生了類型'System.NullReferenceException'的異常,但未在用戶代碼中處理 附加信息:未將對象引用設置爲對象的實例。 – Tom 2014-11-21 05:23:30

-1

如果你ju st獲得一個值,executeScalar()就足夠了。如果您仍然有問題,你可以問

String get; 
Get=cmd.executescalar().tostring(); 
+0

我試過這個:'String getVal = cmd.ExecuteScalar()。ToString();'和代碼拋出一個異常與此消息:類型'System.NullReferenceException'的異常發生在TaskBlasterDBAccessObjects.dll中,但未在用戶中處理代碼 附加信息:未將對象引用設置爲對象的實例。 – Tom 2014-11-21 04:46:04

+0

我希望我沒有誤解你的問題。你想從SQL數據庫獲取返回值嗎?因爲我在兩週前才知道這個問題,我仍然有它的源代碼。 – Rain 2014-11-21 04:52:30

+0

我想從Microsoft SQL Server數據庫上存在的存儲過程獲取返回值。我從我的C#代碼中調用這個存儲過程。 – Tom 2014-11-21 05:00:10

相關問題