T-SQL:将新的插入标识返回给C#

T-SQL:将新的插入标识返回给C#,c#,sql,return-value,scope-identity,C#,Sql,Return Value,Scope Identity,我使用存储过程将值放入SQL Server。该过程将向添加的行添加一个ID。我需要把这个ID恢复到我的代码中 目前,我可以在VisualStudio的“输出”窗口中查看输出id,但似乎无法在代码中捕获它。以下是程序的摘要版本: SQL: CREATE PROCEDURE dbo.DoSomething ( @var1 INT = NULL, @var2 INT = NULL, @var3 DATE = NULL ) AS BEGIN INSERT INTO a

我使用存储过程将值放入SQL Server。该过程将向添加的行添加一个ID。我需要把这个ID恢复到我的代码中

目前,我可以在VisualStudio的“输出”窗口中查看输出id,但似乎无法在代码中捕获它。以下是程序的摘要版本:

SQL

CREATE PROCEDURE dbo.DoSomething
(
    @var1 INT = NULL,
    @var2 INT = NULL,
    @var3 DATE = NULL
)
AS

BEGIN

    INSERT INTO atable
    (
        vara,
        varb,
        varc
    )
    VALUES
    (
        @var1,
        @var2,
        @var3
    )

    RETURN SCOPE_IDENTITY()

END
C#:

int result = 0;

/// create command
SqlCommand cmd = new SqlCommand("DoSomething", this.OpenSqlConnection());
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@var1", thing.value1);
cmd.Parameters.AddWithValue("@var2", thing.value2);
cmd.Parameters.AddWithValue("@var3", thing.value3);


/// send data to db
result = (int)cmd.ExecuteScalar();
因此我得到一个错误:对象引用未设置为对象的实例。当它到达(int)cmd.ExecuteScalar()时

有什么想法吗

...
SELECT SCOPE_IDENTITY()
返回值实际上作为一个特殊的输出参数返回。SELECT为ExecuteScalar提供一个结果集

您也可以使用该子句而不是单独的SELECT:

...
AS
BEGIN
    INSERT INTO atable
    (
        vara,
        varb,
        varc
    )
    OUTPUT INSERTED.IDCol
    VALUES
    (
        @var1,
        @var2,
        @var3
    )
END
GO

这也适用于多行。

您需要添加另一个方向为
ReturnValue
的参数:

var param = cmd.Parameters.Create("@ReturnValue");
param.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(param);
执行后此参数的值将是返回值:

var newId = cmd.Parameters["@ReturnValue"].Value;

Or

var newId = param.Value;

与您得到的错误没有直接关系,但不要将RETURN与SCOPE_IDENTITY()一起使用。存储过程只允许返回使用数据类型int。由于您的标识可以接受其他数据类型,因此您可能会返回非数据类型int的内容。您好,我很难正确返回此内容。谢谢你的建议。在尝试了多种方法之后,我最终尝试了@gbn的建议,这似乎奏效了。@Tomaszewski-请注意,我的原始代码没有将参数添加到参数集合中。答案更新了。对,它是一个单独的参数变量。然后,我在存储过程中添加了@ReturnValue参数。我不断得到一个值,它总是数字8。我不明白为什么。@Tomaszewski-您不需要将ReturnValue参数添加到存储过程参数列表中,您可以使用
RETURN
语句来实现这一点。为了向其他任何人澄清您的语句,“output INSERTED.IDCol”行,IDCol引用了您指定为Identity的ID列。因此,如果列名为“TableId”,则会插入输出。TableId
SqlParameter retval = cmd.Parameters.Add("@returnValue", SqlDbType.Int); 
            retval.Direction = ParameterDirection.ReturnValue;