Ado.net的ExecuteScalar()返回null值

5
我正在使用ado.net通过ExecuteScalar命令在c#中执行存储过程。该存储过程返回新记录的pkey,但ExecuteScalar返回null。我查看数据库并确实添加了一条记录。我可以使用输出参数来获取值,但那样我就不知道为什么会失败。
当我在ssms中执行sp时,pkey被返回。
我做错了什么?
以下是C#代码:
  public int SaveNewPerson(EPerson ePerson)
    {
        int newPersonPkey;
        SqlConnection cn = new SqlConnection(cnn.PersonData);
        using (cn)
        {
            try
            {
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = cn;
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "People.dbo.AddNewPerson"; 
                cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 150).Value = ePerson.LastName;
                cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 150).Value = ePerson.FirstName;
                cn.Open();
                object result = cmd.ExecuteScalar(); 
                newPersonPkey = int.Parse(result.ToString());
                cn.Close();
            }
            catch (Exception e)
            {
                // call error method
                throw new Exception(e.Message + " save new Person error ");
            }
        }
        return newPersonPkey;
    }

这是SP:

 PROCEDURE [dbo].[AddNewPerson]
            @FirstName varchar(50)
           ,@LastName varchar(50) 
AS
BEGIN
    SET NOCOUNT ON;

INSERT INTO [People].[dbo].[Persons]
           (
            [FirstName]
           ,[LastName]
            )
     VALUES
           (
            @FirstName 
           ,@LastName 
           ) 
declare @persons_PKey int 
set @persons_PKey = @@IDENTITY 
return @persons_PKey

end 
2个回答

9
ExecuteScalar方法返回结果的第一行第一列,但是由于你的查询没有返回结果,所以它将返回null。
你可以选择从存储过程中选择值而不是返回它,或者添加一个参数,将方向设置为ParameterDirection.ReturnValue来捕获存储过程的返回值。

当然!我以为这之前已经起作用了。将返回的@persons_PKey更改为选择@persons_PKey,它就可以工作了。 - TheMoot

3
尝试更改存储过程,使用“Select语句”返回标识符,而不是像这样使用返回语句:
SELECT CAST(scope_identity() AS int)

因此,您需要将过程更改为:
 PROCEDURE [dbo].[AddNewPerson]
            @FirstName varchar(50)
           ,@LastName varchar(50) 
AS
BEGIN
    SET NOCOUNT ON;

INSERT INTO [People].[dbo].[Persons]
           (
            [FirstName]
           ,[LastName]
            )
     VALUES
           (
            @FirstName 
           ,@LastName 
           ) 
SELECT CAST(scope_identity() AS int)
end

根据MSDN上ExecuteScalar()的文档,它会返回结果集中第一行的第一列,如果结果集为空,则返回null。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接