2011-06-09 90 views
0

我有以下存儲過程:SQL存儲Procudure沒有返回值

USE [CW] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[addCustomer] 
@firstname VARCHAR(50) = '', 
@lastname VARCHAR(50) = '', 
@email VARCHAR(50) = '', 
@password VARCHAR(50) = '' 


AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 
SELECT * FROM customer WHERE email = @email 

IF (@@ROWCOUNT = 0) 
    BEGIN 
     -- Add to database. 
     INSERT INTO customer (firstname, lastname, email, [password]) 
     VALUES (@firstname, @lastname, @email, @password); 
     SELECT @@IDENTITY; 
    END 
ELSE 
    BEGIN 
     -- Don't add already registered 
     SELECT customer.customerID FROM customer WHERE email = @email; 
    END 


END 

這是給客戶添加到表。如果他們的電子郵件已在表格中,則會返回該客戶的ID。如果電子郵件不在表格中,則創建它並返回新的ID。

問題是,當它創建新記錄時,它返回null。但是當我在Management Studio中執行sproc時,它會顯示正確的返回值。

下面的代碼:

  SqlCommand cmd0 = new SqlCommand(); 
      cmd0.Connection = conn; 
      cmd0.CommandType = CommandType.StoredProcedure; 
      cmd0.CommandText = "addCustomer"; 
      cmd0.Parameters.AddWithValue("@firstname", firstname); 
      cmd0.Parameters.AddWithValue("@lastname", lastname); 
      cmd0.Parameters.AddWithValue("@email", email); 
      cmd0.Parameters.AddWithValue("@password", password); 

      var scaled = cmd0.ExecuteScalar(); 
      customerID = scaled.ToString(); 

的customerID爲空當電子郵件是獨一無二的。

+0

或者發電子郵件給PK:D和溝身份證 – 2011-06-09 22:13:26

+0

無關你的問題,但在幾乎所有情況下'@@ IDENTITY'是錯誤的,使用'scope_identity()'代替。如果每個觸發器都添加到表中,則@ @ IDENTITY不會返回所期望的值。 '@@ IDENTITY':http://msdn.microsoft.com/en-us/library/ms187342.aspx'scope_identity()':http://msdn.microsoft.com/en-us/library/ms190315.aspx – 2011-06-09 23:12:05

回答

2

試試這個:

ALTER PROCEDURE [dbo].[addCustomer] 
    @firstname VARCHAR(50) = '', 
    @lastname VARCHAR(50) = '', 
    @email VARCHAR(50) = '', 
    @password VARCHAR(50) = '' 
AS 

SET NOCOUNT ON; 

IF NOT EXISTS (SELECT * FROM customer WHERE email = @email) 
    INSERT INTO customer (firstname, lastname, email, [password]) 
    VALUES (@firstname, @lastname, @email, @password); 

SELECT customer.customerID FROM customer WHERE email = @email; 

GO 
+0

這是一個很好的建議。 – Nik 2011-06-09 22:19:56

4

您不是返回標量,而是從表中選擇,這是不同的。你想要一個RETURN聲明。另一種方法是使用OUTPUT參數。您可以將C#中的參數設置爲輸出參數,並在運行該過程後,可以從中讀取該值。

2

else是冗餘的,第一條select語句也是這樣做的。我認爲executecalar使用的不是第二個結果集,因此不是@@ identity。

使用該查詢第一

SELECT customer.customerID從客戶WHERE電子郵件= @email;

並擺脫其他。然後使用其他答案建議的返回值方法。

0

格蘭特,

使用@@ ROWCOUNT是不恰當的方式,以確保客戶尚未進入。它只是告訴你,當你檢查時,顧客不在桌子上。

正確的方法是對電子郵件列應用唯一約束。然後嘗試插入客戶行。如果行插入,則輸入客戶。如果你得到一個獨特的違規,那麼客戶已經存在,你可以選擇/返回客戶ID。

一旦這個工作做了什麼尼克已經說過。

+0

我不確定依靠錯誤是最佳實踐。 – gunwin 2011-06-09 22:40:25

+0

如果您不這樣做,那麼您必須在插入期間鎖定所有資源,或者您需要處理在檢查時間之後不同的流程插入客戶時您將獲得的密鑰違規和你插入的時間。無論哪種方式,你必須處理重要違規行爲。你也可以在前面做。 – 2011-06-09 22:55:40

+0

如果你有兩個獨特的領域,你永遠不會知道哪個創造了問題。 – JeffO 2011-06-10 01:17:30