foreach循环中只有第一个存储过程可以工作,但内联查询可以吗?C#

本文关键字:查询 工作 第一个 存储过程 foreach 循环 | 更新日期: 2023-09-27 18:28:29

我正试图使用foreach循环向表中插入几行数据,当我编写内联SQL时,它似乎可以正常工作;

connection.Open();
foreach (Bet bet in bets)
{
    string insertQuery = "insert into BetTbl (FixtureId,BetTime,UserName,PlayerId) values (@FixtureId, @BetTime, @UserName, @PlayerId)";
    SqlCommand command = new SqlCommand(insertQuery, connection);
    command.Parameters.AddWithValue("@FixtureId", bet.FixtureId);
    command.Parameters.AddWithValue("@BetTime", bet.BetTime);
    command.Parameters.AddWithValue("@UserName", bet.User);
    command.Parameters.AddWithValue("@PlayerId", bet.PlayerId);
    command.ExecuteNonQuery();
}
bets.Clear();
connection.Close();

但是当我尝试使用存储过程时,我会遇到一个错误;

过程或函数InsertBets指定的参数太多

这是代码:

connection.Open();
foreach (Bet bet in bets)
{
    command.Connection = connection;
    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = "InsertBets";
    command.Parameters.AddWithValue("@FixtureId", bet.FixtureId);
    command.Parameters.AddWithValue("@BetTime", bet.BetTime);
    command.Parameters.AddWithValue("@UserName", bet.User);
    command.Parameters.AddWithValue("@PlayerId", bet.PlayerId);
    command.ExecuteNonQuery();
}
bets.Clear();
connection.Close();

这是存储过程:

CREATE PROCEDURE [dbo].[InsertBets]
    @FixtureId  VARCHAR(50),
    @BetTime    VARCHAR(25),
    @UserName   NVARCHAR(20),
    @PlayerId   VARCHAR(25)
AS
    INSERT INTO dbo.BetTbl (FixtureId, BetTime, UserName, PlayerId)
    VALUES (@FixtureId, @BetTime, @UserName, @PlayerId)

虽然它使用内联SQL可以工作,但我不明白为什么它不使用存储过程,有人能告诉我为什么吗?感谢

foreach循环中只有第一个存储过程可以工作,但内联查询可以吗?C#

在第一个代码示例中,每次迭代都会创建一个新的SqlCommand

SqlCommand command = new SqlCommand(insertQuery, connection);

在第二个迭代中,所有迭代都修改相同的命令,添加越来越多的参数。只有第一个调用会有正确数量的参数,下一个调用的参数太多。

在没有值的循环之前添加参数,然后在循环中设置值并执行命令

command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "InsertBets";
command.Parameters.Add("@FixtureId", SqlDbType.Int);
// add the other paramters
foreach (Bet bet in bets)
{
    command.Parameters["@FixtureId"].Value = bet.FixtureId;
    // set the other parameters
    command.ExecuteNonQuery();
}

每次循环时都会向命令变量添加参数。您第一次循环并使用添加参数

command.Parameters.AddWithValue

然后第二次循环,并使用添加参数

command.Parameters.AddWithValue

问题是,以前的参数仍然存在。您必须清除参数或从头开始重新实例化变量。

答案(可能)在您没有显示的部分->command在哪里以及如何定义和初始化。

由于在foreach循环中使用AddWithValue(),因此每次迭代都要添加值字段,因此第一次迭代有4个字段,第二次迭代有8个字段,然后是12个字段,依此类推

相反,在初始化command时添加一次字段,然后只在foreach循环中设置值。


顺便说一句,AddWithValue()通常被认为是一种糟糕的做法。

尝试更改您的编码样式

 cmd.Parameters.Add(new SqlParameter("@FixtureId", bet.FixtureId));

我还认为您每次都需要在循环中创建命令,而不是在循环外

您正在调用命令。Parameters.AddWithValue,并在每次循环时添加更多值。清除()每个循环的参数,或者初始化Command的新实例。