Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C返回异常:过程没有参数,并且提供了参数_C#_Asp.net_Sql Server_Stored Procedures_Parameters - Fatal编程技术网

C# C返回异常:过程没有参数,并且提供了参数

C# C返回异常:过程没有参数,并且提供了参数,c#,asp.net,sql-server,stored-procedures,parameters,C#,Asp.net,Sql Server,Stored Procedures,Parameters,对此我深表歉意。我是编程新手,也是这个网站的新手,所以我会尽量把问题弄清楚 我有一个用于访问/修改客户数据库的网络表单。我有一个按钮,用于输入新客户的详细信息,该按钮将通过从数据库中获取最高的ID号自动分配一个ID号,并递增1,然后发布到表单文本框 这是我写的代码: protected void btnNew_Click(object sender, EventArgs e) { Clear(); command.Connection = conn;

对此我深表歉意。我是编程新手,也是这个网站的新手,所以我会尽量把问题弄清楚

我有一个用于访问/修改客户数据库的网络表单。我有一个按钮,用于输入新客户的详细信息,该按钮将通过从数据库中获取最高的ID号自动分配一个ID号,并递增1,然后发布到表单文本框

这是我写的代码:

protected void btnNew_Click(object sender, EventArgs e)
{
        Clear();

        command.Connection = conn;
        command.CommandType = CommandType.StoredProcedure;
        command.CommandText = "NewCustomer";

        conn.Open();

        SqlParameter maxid = new SqlParameter();
        maxid.ParameterName = "@MaxID";
        maxid.SqlDbType = SqlDbType.Int;
        maxid.Direction = ParameterDirection.Output;
        command.Parameters.Add(maxid);

        command.ExecuteNonQuery();                       

        NewCustId = Convert.ToInt32(maxid.Value);
        NewCustId += 1;

        txtCustID.Text = (NewCustId).ToString();
        txtCustID.DataBind();

        conn.Close();
}
这是存储过程:

CREATE PROCEDURE NewCustomer
    (@MaxID INT OUTPUT)
AS
BEGIN
    SELECT @MaxID = MAX(CustID)
    FROM dbo.Customer
END
我尝试了许多不同的编码方法,但似乎都不管用。 我发布的代码在ExecuteOnQuery中有一个异常,表示提供了参数,并且过程没有参数。当我放置command.Parameters.Addmaxid时;在ExecuteOnQuery下面,它返回1

我单独运行SQL查询以查看会发生什么,它会在未命名的单元格中返回正确答案。出于某种原因,列名出现时会消失。然后,当我尝试使用C代码访问未命名的单元格时,我似乎无法访问它,因为“CustID”列不存在

有了这段代码,我知道SQL命令正在执行,然后C代码递增1,但我得到的返回值似乎是0

我很感激我能得到的关于如何解决这个问题的任何想法。多谢各位

编辑:我也尝试过: DataTable=新的DataTable; 适配器。可填充; NewCustId=table.Rows[0].FieldCustID


这就是它所说的“CustID”列不存在的地方

ExecuteOnQuery不需要任何结果。请改用ExecuteReader。

将代码更改为以下内容,然后重试:

 Clear();
    command.Connection = conn;
    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = "NewCustomer";
    conn.Open();
    NewCustId = Convert.ToInt32(cmd.ExecuteScalar().ToString()); 
    NewCustId += 1;
    txtCustID.Text = NewCustId.ToString();
    conn.Close();
您的存储过程是:

CREATE PROCEDURE NewCustomer
(

)
AS
BEGIN
   SELECT MAX(CustID)
     FROM dbo.Customer;
END

我赞同marc_关于这个问题的看法。 由于您使用max ID并递增1在数据库中插入新记录,因此我建议您对此列使用Identityseed、increment_值。 这样,您就不必找到max来插入新记录,并且可以避免许多事务问题。 一旦交易完成

可能的设计:

Create Table Customer
(
    Id Int Identity(1,1), 
    Name varchar(50)
)
Create Proc NewCustomer 
(
    @Name varchar(50)
)
As
(
    DECLARE @custID Int
    SET NOCOUNT ON
    INSERT INTO Customer (Name) Values('Your Name')
    SET @custID = SCOPE_IDENTITY()
    RETURN @custID
)
protected void btnNew_Click(object sender, EventArgs e)
{
        Clear();
        command.Connection = conn;
        command.CommandType = CommandType.StoredProcedure;
        command.CommandText = "NewCustomer";

        conn.Open();
        SqlParameter name = new SqlParameter();
        name.ParameterName = "@Name";
        name.Direction = ParameterDirection.Input;
        name.SqlDbType = SqlDbType.Varchar;
        name.Value = "Your Name";
        command.Parameters.Add(name);
        SqlParameter returnValue= new SqlParameter();
        returnValue.ParameterName = "@custID";
        returnValue.SqlDbType = SqlDbType.Int;
        returnValue.Direction = ParameterDirection.ReturnValue;
        command.Parameters.Add(maxid);

        command.ExecuteNonQuery();                       

        NewCustId = Convert.ToInt32(returnValue.Value);

        txtCustID.Text = (NewCustId).ToString();
        txtCustID.DataBind();

        conn.Close();
}

是的,或者ExecuteScalari尝试了ExecuteReader和ExecuteScalar,但都得到了相同的异常消息。一个词:不要这样做!这在繁忙的系统中无法可靠地工作-您迟早会得到副本!相反,请使用SQL Server自身更新的INT-IDENTITY列的SQL Server内置机制,并确保不使用任何值两次…..这一行的用途是什么;您已经将该值分配给此处的文本框txtCustID.Text=NewCustId.ToString;您可以使用txtCustID.Text=Convert.ToStringNewCustId;我知道您发布了几种解决方案,但您应该阅读并注意@marc_s的警告。您正在做的事情将会失败,并在将来造成巨大的痛苦。您只需执行以下操作,编辑存储过程SELECT@MaxID=MAXCustID FROM dbo。Customer@marc_s谢谢你的小费。我知道,为繁忙的数据库创建唯一ID是一种不可靠的方法。不幸的是,我不熟悉自动身份证系统,因为我只是这方面的一名学生。@marc_他试图给出参数,所以我用参数来表示他完美!非常感谢。我是编程新手,所以我希望有一个简单的解决方案。另外,我如何选择这个作为我帖子的答案?@DaveOli特别是因为你是编程新手,我再次建议你放弃这种方法。这是一个比赛条件。如果两个人同时插入新行,则可能会返回错误的值。这是一个原因,身份将是一个更好的方法。这当然是你的决定,但你会在某个时候感到痛苦,这会让你发疯,试图找出哪里出了问题。@DaveOli你会后悔走这条路:你最好的选择是做对它,即使这个应用程序非常小,否则当你将相同的解决方案用于现实世界的应用程序时,它会咬你的背因为并发性而产生问题。@SeanLange&Paolo谢谢。是的,我知道这是一个坏习惯,但我正处于学习的初级阶段,目前正在进行网络开发。稍后我将学习一门单独的SQL课程,因此我计划进一步了解有关良好数据库协议的详细信息。谢谢。我也会试试,看看能不能让它工作。谢谢你!