繁体   English   中英

C#和SQL Server存储过程-无法获取输出参数值,返回值有效

[英]C# & SQL Server stored procedures - can't get output parameter value, return value works

我想获取存储过程的输出参数的值,但是我一直都在+1 通过返回获取值时,一切正常。

我设法使用Entity Framework获得了输出参数的值,但是,它的运行速度确实很慢。 我附加了存储过程和用于从存储过程中获取值的C#代码。

具有输出参数的存储过程在SQL Server中可以正常工作。

有人知道为什么我的代码不起作用吗?

感谢您的帮助。

存储过程:

Create procedure sp_CountEachNumberOccurencesOutput
    @number tinyint, 
    @count_number int output
As
    SET NOCOUNT ON

    select count(*) 
    from RawData
    where Number1 = @number or Number2 = @number or Number3 = @number

    select @count_number = count(*)

具有和输出参数的存储过程的C#代码使用Entity Framework并且可以运行,但是速度很慢:

using (SqlConnection cn = new SqlConnection(cnStr))
{
    cn.Open();

    using (SqlCommand cmd = new SqlCommand("sp_CountEachNumberOccurencesOutput", cn))
    {
        var outParam = new SqlParameter();
        int outputValue = 0;
        outParam.SqlDbType = SqlDbType.Int;
        outParam.Direction = ParameterDirection.Output;

        DbContext dbContext = new DbContext(this.connectionString);

        var data = dbContext.Database.SqlQuery<int>("sp_CountEachNumberOccurencesOutput @number, @count_number OUT",
                   new SqlParameter("number", parameter),
                   new SqlParameter("count_number", outputValue),
                   outParam);

        outputValue = data.ToList()[0];

        return outputValue;
    }
}

带有和输出参数的存储过程的C#代码不起作用:

using (SqlConnection cn = new SqlConnection(cnStr))
{
    cn.Open();

    using (SqlCommand cmd = new SqlCommand("sp_CountEachNumberOccurencesOutput", cn))
    {
        cmd.CommandType = CommandType.StoredProcedure;

        SqlParameter param = cmd.Parameters.Add("@number", SqlDbType.Int);
        param.Direction = ParameterDirection.Input;
        param.Value = parameter;

        SqlParameter outputParameter = cmd.Parameters.Add("@count_number", SqlDbType.Int);
        outputParameter.Direction = ParameterDirection.Output;
        outputParameter.Value = 0;                   

        cmd.ExecuteNonQuery();

        cn.Close();

        int OutputValue = (int)cmd.Parameters["@count_number"].Value;

        return OutputValue;
    }
}

此代码获取返回值并起作用:

using (SqlConnection cn = new SqlConnection(cnStr))
{
    cn.Open();

    using (SqlCommand cmd = new SqlCommand("sp_CountEachNumberOccurencesReturn", cn))
    {
        cmd.CommandType = CommandType.StoredProcedure;

        SqlParameter param = cmd.Parameters.Add("@number", SqlDbType.Int);
        param.Direction = ParameterDirection.Input;
        param.Value = parameter;

        SqlParameter returnValue = new SqlParameter();
        returnValue.Direction = ParameterDirection.ReturnValue;
        cmd.Parameters.Add(returnValue);

        return Convert.ToInt32(cmd.ExecuteScalar());
    }
}

不知道是否可以将count(*)分配给参数。 它仅在sql语句中有效。

也许试试这个

Create procedure sp_CountEachNumberOccurencesOutput
    @number tinyint, @count_number int output
    As
    SET NOCOUNT ON
    select @counter_number=count(*)  from RawData
                where Number1 = @number or Number2 = @number  or Number3 = @number

我以前执行此任务的方法如下:

public Int32 ExecuteGenericSP(string spName, out int errNum, out string errMsg, params object[] lstParams)
{
    Int32 returnValue;
    /* Aqui */
    SqlDatabase _sqlDatabase = new SqlDatabase(getConnectionString());
    using (DbConnection con = _sqlDatabase.CreateConnection())
    {
        DbCommand cmd = _sqlDatabase.GetStoredProcCommand(spName);
        _sqlDatabase.DiscoverParameters(cmd);
        int n = 3;

        errNum = 0;
        errMsg = "";
        cmd.Parameters["@RETURN_VALUE"].Value = 0;

        cmd.Parameters["@errNum"].Value = 0;
        cmd.Parameters["@errDes"].Value = "";

        foreach (object o in lstParams)
        {
            if (cmd.Parameters[n].DbType.ToString() == "DateTime")
                cmd.Parameters[n].Value = Convert.ToDateTime(o);
            else
                cmd.Parameters[n].Value = o.ToString();
            n++;
        }

        returnValue = _sqlDatabase.ExecuteNonQuery(cmd);

        errNum = Convert.ToInt16(_sqlDatabase.GetParameterValue(cmd, "errNum"));
        errMsg = _sqlDatabase.GetParameterValue(cmd, "errDes").ToString();
    }
    return returnValue;
}

例如,这是SP的示例:

ALTER PROCEDURE [dbo].[AUD_Insertar]
    @errNum smallint OUTPUT,
    @errDes varchar(50) OUTPUT,
    @id smallint,    
    @message varchar(MAX),
    @type char(1),
    @userId varchar(20),
    @modulo char(1)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    SET @errNum = 0;
    SET @errDes = '';

    INSERT INTO log(message, type, userId, modulo) VALUES (@message, @type, @userId, @modulo)
    IF (@@ROWCOUNT = 0)
    BEGIN
        SET @errNum = 1;
        SET @errDes = 'Error while inserting';
    END
END

希望对您有所帮助。 问候,

阿德里安

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM