C# C返回异常:过程没有参数,并且提供了参数
对此我深表歉意。我是编程新手,也是这个网站的新手,所以我会尽量把问题弄清楚 我有一个用于访问/修改客户数据库的网络表单。我有一个按钮,用于输入新客户的详细信息,该按钮将通过从数据库中获取最高的ID号自动分配一个ID号,并递增1,然后发布到表单文本框 这是我写的代码: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;
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课程,因此我计划进一步了解有关良好数据库协议的详细信息。谢谢。我也会试试,看看能不能让它工作。谢谢你!