此SqlParameterCollection函数不包含参数名称为'@name'的SqlParameter

时间:2018-08-22 01:14:22

标签: c# sql-server-2008

我正在尝试从下面的代码中返回一个值,但出现一条错误消息:

  

此SqlParameterCollection不包含参数名称为'@vRESULT'的SqlParameter

c#代码:

public int userLogin()
{
    string connStr = ConfigurationManager.ConnectionStrings["conn"].ToString();
    string cmdStr = @"fucn_LOg";

    using (SqlConnection conn = new SqlConnection(connStr))
    using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
    {
        try
        {
            conn.Open();
            cmd.CommandText = cmdStr;
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Clear();

            cmd.Parameters[":vResult"].Direction = ParameterDirection.Output;

            cmd.Parameters.Add(new SqlParameter("param1", SqlDbType.VarChar)).Value = TB_1.Text;
            cmd.Parameters.Add(new SqlParameter("param2", SqlDbType.VarChar)).Value = TB_2.Text;

            cmd.ExecuteScalar();

            return Int32.Parse(cmd.Parameters[":vResult"].Value.ToString());
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
            return -1;
        }
    }
}

以下带有返回参数DECLARE @vResult int的sql server函数代码

CREATE FUNCTION USER_LOGIN(@USER_NAME VARCHAR(60),
                           @PWD VARCHAR(60))
RETURNS INT

AS BEGIN 

DECLARE @vResult int

SELECT @vRESULT=COUNT(*) 
    FROM OPER 
WHERE  UPPER(UNAM)=UPPER(@USER_NAME) 
   AND PSW=@PWD

IF @vResult=1
    SET @vResult=1
ELSE
    SET @vResult= -1

RETURN @vResult
END

3 个答案:

答案 0 :(得分:1)

几个问题。

首先,您无需cmd.Parameters.Clear();,只需建立一个新的cmd。

第二,将@用于SQL Server参数。

第三,未设置名为vResult的参数,因此cmd.Parameters[":vResult"].Direction无效。您需要分配其类型和值。确保您的存储过程已使用正确的SQL数据类型设置了此参数。

最后,我猜想您在vResult之类的存储过程中返回了select @vResult;,因此将其设为new vResult = function(vResult)。但是,不是,这不是SQL Server的工作方式。即使您返回@vResult,它也不会更改您的输入参数。同时,ExecuteScaler可以。因此,只需通过var result = cmd.ExecuteScalar();即可返回结果。

您正在从存储过程获取数据,而不是获取发送的参数。那是假定的正确方法。

conn.Open();
cmd.CommandText = cmdStr;
cmd.CommandType = CommandType.StoredProcedure;

//Base on sql you provided, it is no need for this part.
/*
SqlParameter vResult = new SqlParameter();
vResult.ParameterName = "@vResult";
vResult.Direction = ParameterDirection.Output;
vResult.SqlDbType = System.Data.SqlDbType.???;
vResult.Value = ???;
cmd.Parameters.Add(vResult);
*/
cmd.Parameters.Add("@param1", SqlDbType.VarChar).Value = TB_1.Text;
cmd.Parameters.Add("@param2", SqlDbType.VarChar).Value = TB_2.Text;

var result = cmd.ExecuteScalar();

return Int32.Parse(result.ToString());

答案 1 :(得分:1)

只需从Stroed Procedure中获得结果,即可:

var result = cmd.ExecuteScalar();
return Int32.Parse(result.ToString());

这是存储过程的第一个也是唯一的结果。

还建议您像这样简化代码:

public int userLogin() {
    string connStr = ConfigurationManager.ConnectionStrings["conn"].ToString();

    using (SqlConnection conn = new SqlConnection(connStr))
    using (SqlCommand cmd = new SqlCommand("fucn_LOg", conn)) {
        try {
            cmd.Connection.Open();
            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            cmd.Parameters.AddWithValue("@param1", TB_1.Text);
            cmd.Parameters.AddWithValue("@param2", TB_2.Text);

            var result = cmd.ExecuteScalar();
            return Int32.Parse(result.ToString());
        }
        catch (Exception ex) {
            MessageBox.Show(ex.ToString());
            return -1;
        }
        finally {
            if (cmd.Connection.State != ConnectionState.Closed) cmd.Connection.Close();
        }
    }
}

您的存储过程应如下所示:

CREATE PROCEDURE fucn_LOg 
(
    @param1         nvarchar(max),
    @param2         nvarchar(max)
)
AS
BEGIN
    SET NOCOUNT ON;

    if (exists(select * from tbUsers where flLogin = @param1 and flPassword = @param2))
    begin
        return 1;
    end
    else
    begin
        return 0;
    end
END
GO

OR

CREATE PROCEDURE fucn_LOg
(
    @param1         nvarchar(max),
    @param2         nvarchar(max)
)
AS
BEGIN
    SET NOCOUNT ON;

    select COUNT(*) from tbUsers where flLogin = @param1 and flPassword = @param2    
END
GO

答案 2 :(得分:0)

如果没有SP,这很难调试,但是有些事情会跳出来。

首先,您需要使用'@'字符作为参数名称的前缀,而不是冒号。

第二,您应该像这样定义输出参数:

SqlParameter outputParam = new SqlParameter("@vResult", SqlDbType.Int);
outputParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(outputParam);