【问题标题】:Issue with correct results when using a stored procedure vs a query statement使用存储过程与查询语句时出现正确结果的问题
【发布时间】:2016-09-06 15:47:01
【问题描述】:

我有这个网络应用程序,用户使用复选框列表和文本框在网络表单中输入数据以输入值和日期。然后使用存储过程将输入的这些值更新到数据库中。

使用存储过程时,webapp 可以正常工作,但如果我改用Update 语句,它会使用用户输入的值乘以数据库中选择的项目数来更新数据库。

例如,如果checkboxlist中有11个项目,所有项目都被选中,使用存储过程,如果用户输入12,则数据库中的每个值都是12,但是使用更新语句,输入的每个值都是132 ,谁能向我解释为什么会这样,是否有办法获得与存储过程相同的结果?

CREATE TABLE AccountTable
(
    RowID int IDENTITY(1, 1),
    AccountID varchar(2),
    AccountName varchar(50),
    SeqNum int,
    SeqDate datetime
)

CREATE PROCEDURE [ACCOUNTTABLE_UPDATE]
    (@SeqNum int,
     @SeqDate datetime,
     @Account_ID varchar(2)
    )
AS 
    SET NOCOUNT ON

    BEGIN
        UPDATE AccountTable
        SET SeqNum = SeqNum + @SeqNum, SeqDate =  @SeqDate
        WHERE AccountID = @AccountID
   END

C#代码:

DateTime dt = DateTime.Now;
DateTime.TryParseExact(datepicker.Text, "mmddyyyy", provider, style out dt);

int i = Int32.Parse(TextBox1.Text);
//DropDownList Binded from database values in another method

SqlConnection con = new SqlConnection(GetConnString());

SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[dbo].[Table_Update]";

//Update Query cmd.CommandText = "Update Account Table SET SeqNum = SeqNum + @SeqNum, SeqDate = @SeqDate WHERE AccountID = @AccountID;";

cmd.Parameters.AddWithValue("@SeqNum", SqlDbType.Int).Value = i
cmd.Parameters.AddWithValue("@SeqDate",SqlDbType.DateTime).Value = DateTime.Now;
cmd.Parameters["@Account_ID", SqlDbType.VarChar).Value = CheckBoxList1.SelectedValue;

foreach (ListItem item in CheckBoxList.Items)
{
     if (item.Selected)
     {
         cmd.Parameters["@SeqNum"].Value = i;
         cmd.Parameters["@SeqDate"].Value = DateTime.Now;
         cmd.Parameters["@Account_ID"].Value = item.Value;

          try
          {
             con.Open();
             cmd.ExecuteNonQuery();
          }
          catch (SqlException ex)
          {
              Response.Write(ex.Message);
              //Database Exceptions
          }
          finally
          {
              con.Close();
          }
     }
}

【问题讨论】:

  • 在更新查询中,如果数据库中已经有一个值,它会将用户输入的数字加上为选定的特定“Account_ID”设置的表中已有的数字。
  • 您定义了两次参数 - 为什么会这样?是否有任何代码没有向我们展示i 被操纵的位置?
  • @user1666620 或DateTime.Now
  • 将循环移动到 con.Open/con.Close 语句中可能是个好主意,这样您也只使用一个连接。将您的 com 移到循环内,将您的 con 移到循环外。这样你就不会添加到同一个com,而是每次都创建一个新的

标签: c# asp.net sql-server stored-procedures


【解决方案1】:

怎么样:

 public void data2()
    {
        DateTime dt = DateTime.Now;
        DateTime.TryParseExact(datepicker.Text, "mmddyyyy", provider, style out dt);

        int i = Int32.Parse(TextBox1.Text);
        int check = 0;
        //DropDownList Binded from database values in another method

        foreach (ListItem item in CheckBoxList.Items)
        {
            if (item.Selected)
            {

                check++;
            }
        }
        using (SqlConnection conn = GetConnString())
        {
            conn.Open();

            using (SqlCommand cmd = new SqlCommand())
            {
                //    cmd.CommandType = CommandType.StoredProcedure;
                //cmd.CommandText = "[dbo].[Table_Update]";
                cmd.CommandText = "Update Account Table SET SeqNum = SeqNum + @SeqNum, SeqDate = @SeqDate WHERE AccountID = @AccountID";
                cmd.Parameters.AddWithValue("@SeqNum", check);
                cmd.Parameters.AddWithValue("@SeqDate", DateTime.Now);
                cmd.Parameters["@Account_ID", CheckBoxList1.SelectedValue);
                cmd.ExecuteNonQuery();
            }


            conn.Close();
        }
    }

或者,它 TextBox1.Text 已经是你要保存的数字了...

    public void data3()
    {
        DateTime dt = DateTime.Now;
        DateTime.TryParseExact(datepicker.Text, "mmddyyyy", provider, style out dt);

        int i = Int32.Parse(TextBox1.Text);
                    //DropDownList Binded from database values in another method

        using (SqlConnection conn = GetConnString())
        {
            conn.Open();

            using (SqlCommand cmd = new SqlCommand())
            {
                //    cmd.CommandType = CommandType.StoredProcedure;
                //cmd.CommandText = "[dbo].[Table_Update]";
                cmd.CommandText = "Update Account Table SET SeqNum = SeqNum + @SeqNum, SeqDate = @SeqDate WHERE AccountID = @AccountID";
                cmd.Parameters.AddWithValue("@SeqNum", TextBox1.Text);
                cmd.Parameters.AddWithValue("@SeqDate", DateTime.Now);
                cmd.Parameters["@Account_ID", CheckBoxList1.SelectedValue);
                cmd.ExecuteNonQuery();
            }


            conn.Close();
        }
    }

注意,在这两种情况下,因为您的 SQL 包含“SeqNum = SeqNum + @SeqNum”,它将保存运行总数,将此处选择的图片添加到之前选择的任何图片中。如果您不想这样做,请将您的 SQL 修改为“SeqNum = @seqNum”,它将修改为仅在此页面加载期间选择的数字。

【讨论】:

  • 感谢 Shannon,存储过程工作正常,但如果我使用与存储过程中相同的语句的更新查询,我会得到错误的结果。
  • 即使这确实有效,这也是一个糟糕的答案,因为它没有解释错误是什么或您提供的代码如何更好。
  • 我在上面的评论中描述了这一点。 “将您的 conn 移出循环并将您的 com 移到循环内,这样您就不会一遍又一遍地添加到同一个 com 中,而是创建一个新的”
  • 我很抱歉,我确实读过,当我执行更改时会告诉你结果。
  • 不用担心 - 顺便说一句,我忘了在 conn.Open() 中移动 foreach 循环 - 它会像我最初输入的那样工作,但编辑应该会更好。这假设总是至少有一个复选框被选中。如果它有时为空,您可能需要更改逻辑,使其不会不必要地打开/关闭连接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多