在执行更新查询时获取主键作为输出或 return?

Get the primary key as output or return when you performing an Update query?

我正在尝试获取主键的输出参数,即 ID。当我执行更新查询时,我得到 Null。你能推荐一种方法吗?

CREATE PROCEDURE sp_InsertTax
    (@ID int output, 
     @TaxAuthorityID int, 
     @TaxClassificationID int, 
     @EntityID int, 
     @AppliesTo_TaxEntityTypeID int)
AS
    IF EXISTS (SELECT * FROM Tax 
               WHERE TaxAuthorityID = @TaxAuthorityID  
                 AND TaxClassificationID = @TaxClassificationID 
                 AND EntityID = @EntityID 
                 AND AppliesTo_TaxEntityTypeID = @AppliesTo_TaxEntityTypeID)
    BEGIN
        UPDATE Tax 
        SET TaxAuthorityID = @TaxAuthorityID, 
            TaxClassificationID = @TaxClassificationID, 
            EntityID = @EntityID, 
            AppliesTo_TaxEntityTypeID = @AppliesTo_TaxEntityTypeID
        WHERE ID = @ID 
    END
    ELSE 
    BEGIN
        IF @ID IS NULL
        BEGIN
            INSERT INTO Tax(TaxAuthorityID, TaxClassificationID, EntityID, AppliesTo_TaxEntityTypeID)
            VALUES (@TaxAuthorityID, @TaxClassificationID, @EntityID, @AppliesTo_TaxEntityTypeID)

            SET @ID = Scope_Identity()
        END
    END
GO

下面是我的 ADO.NET 调用更新存储过程的代码:

public int InsertFederalTax(int ClassificID, int appliesTo)       
{
    int tax_id = 0;
    Sqlconn.Open();

    SqlCommand cmd = new SqlCommand("sp_InsertTax", Sqlconn);
    cmd.CommandType = CommandType.StoredProcedure;

    var returnparameter = cmd.Parameters.AddWithValue("ID", SqlDbType.Int);
    returnparameter.Direction = ParameterDirection.Output;

    cmd.Parameters.Add("@TaxAuthorityID", SqlDbType.Int).Value = 1;
    cmd.Parameters.Add("@TaxClassificationID", SqlDbType.Int).Value = ClassificID;
    cmd.Parameters.Add("@EntityID", SqlDbType.Int).Value = 0;
    cmd.Parameters.Add("@AppliesTo_TaxEntityTypeID", SqlDbType.Int).Value = appliesTo;

    cmd.ExecuteNonQuery();

    if (!(returnparameter.Value is DBNull))
        tax_id = Convert.ToInt32(returnparameter.Value);
                                 
    Sqlconn.Close();
    return tax_id;
}

请尝试使用以下更新更改您的 C# 代码,并向我们提供反馈:

public int InsertFederalTax(int ClassificID, int appliesTo)       
{
    int tax_id = 0;
    Sqlconn.Open();

    SqlCommand cmd = new SqlCommand("sp_InsertTax", Sqlconn);
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.Add("@ID", SqlDbType.Int);  
    cmd.Parameters["@ID"].Direction = ParameterDirection.Output; 

    cmd.Parameters.AddWithValue("@TaxAuthorityID", 1);
    cmd.Parameters.AddWithValue("@TaxClassificationID", ClassificID);
    cmd.Parameters.AddWithValue("@EntityID", 0);
    cmd.Parameters.AddWithValue("@AppliesTo_TaxEntityTypeID", appliesTo);

    cmd.ExecuteNonQuery();

    if(!(cmd.Parameters["@ID"].Value is DBNull))
    {
       tax_id = Convert.ToInt32(cmd.Parameters["@ID"].Value);
    }
                                 
    Sqlconn.Close();
    return tax_id;
}

我认为您打算捕获现有重复记录的 ID,您可以按如下方式进行。我还为 SP 添加了最佳实践模板项。另请注意 marc_c 关于不在您的 SP 前加上 sp_.

的评论
CREATE PROCEDURE InsertTax
(
   @ID int output 
   , @TaxAuthorityID int 
   , @TaxClassificationID int 
   , @EntityID int 
   , @AppliesTo_TaxEntityTypeID int
)
AS
BEGIN
    SET NOCOUNT, XACT_ABORT ON;

    -- This assumes that none of the parameters can ever be null
    -- And from your comments we know that no duplicates can exist
    SELECT @ID = ID
    FROM Tax 
    WHERE TaxAuthorityID = @TaxAuthorityID  
    AND TaxClassificationID = @TaxClassificationID 
    AND EntityID = @EntityID 
    AND AppliesTo_TaxEntityTypeID = @AppliesTo_TaxEntityTypeID;

    IF @ID IS NOT NULL BEGIN
        UPDATE Tax 
        SET TaxAuthorityID = @TaxAuthorityID, 
            TaxClassificationID = @TaxClassificationID, 
            EntityID = @EntityID, 
            AppliesTo_TaxEntityTypeID = @AppliesTo_TaxEntityTypeID
        WHERE ID = @ID;
    END; ELSE BEGIN
        INSERT INTO Tax (TaxAuthorityID, TaxClassificationID, EntityID, AppliesTo_TaxEntityTypeID)
            VALUES (@TaxAuthorityID, @TaxClassificationID, @EntityID, @AppliesTo_TaxEntityTypeID);

        SET @ID = SCOPE_IDENTITY();
    END;

    RETURN 0;
END;
GO

我建议将您的 return 参数声明为:

var returnparameter = new SqlParameter("@ID", SqlDbType.Int)
{
    Direction = ParameterDirection.InputOutput
};

cmd.Parameters.Add(returnparameter);