2011-06-09 85 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