【问题标题】:SqlCommand SQL insert with ExecuteNonQuery inserting 2 rowsSqlCommand SQL 插入 ExecuteNonQuery 插入 2 行
【发布时间】:2020-03-12 17:55:26
【问题描述】:

我在表格中有一个按钮,调用插入语句,

private void bttnEnroll_Click(object sender, RoutedEventArgs e)
{
            string className;
            string section;

            SqlConnection sqlCon = new SqlConnection(@"Data Source=DESKTOP-7S08N90;Initial Catalog=UniversityDB;Integrated Security=True");
            try
            {
                DataRowView row = (DataRowView)((Button)e.Source).DataContext;
                className = row[0].ToString();
                section = row[1].ToString();

                if (sqlCon.State == ConnectionState.Closed)
                    sqlCon.Open();

                //SQL query
                String query = "INSERT INTO Takes (studentID, className, section, semester, year, time, grade) " +
                               "SELECT @studentID, className, section, @semester, @year, time, @grade " +
                               "FROM Section " +
                               "WHERE className=@className " +
                               "AND section=@section";
                SqlCommand sqlCmd = new SqlCommand(query, sqlCon);
                sqlCmd.Parameters.AddWithValue("@studentID", this.studentID);
                sqlCmd.Parameters.AddWithValue("@className", className);
                sqlCmd.Parameters.AddWithValue("@section", section);
                sqlCmd.Parameters.AddWithValue("@semester", this.semester);
                sqlCmd.Parameters.AddWithValue("@year", this.year);
                sqlCmd.Parameters.AddWithValue("@grade", "N/A");

                int rowsAffected = sqlCmd.ExecuteNonQuery();
                if (rowsAffected == 1)
                {
                    MessageBox.Show("Class enrolled.");
                }
                else if (rowsAffected > 1)
                {
                    MessageBox.Show("More than 1 row affected");
                } else
                {
                    MessageBox.Show("Class not enrolled.");
                }
                sqlCmd.Dispose();
            }
            catch (Exception ex) //if SQL server connection fails
            {
                MessageBox.Show(ex.Message.ToString() + ". Class failed to enroll.");
            }
            finally
            {

                sqlCon.Close();
            }
}

最初我以为我可能在某处执行了两次该语句,但我在

上设置了一个断点
int rowsAffected = sqlCmd.ExecuteNonQuery();

它返回 2。检查数据库显示插入了 2 行重复数据,而我只想要 1。

完整代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace UniversityDBInterface
{
    /// <summary>
    /// Interaction logic for Results.xaml
    /// </summary>
    public partial class Results : Window
    {
        int studentID;
        string semester;
        string year;
        int deptID;
        int courseNum;
        string comparison;
        Boolean days;
        Boolean open;
        public Results(String semester, String year, int deptID, int courseNum, String comparison,
                        Boolean days, Boolean open, int studentID)
        {
            //init
            InitializeComponent();
            this.studentID = studentID;
            this.semester = semester;
            this.year = year; //TODO: ? not sure if this is necessary in our implementation
            this.deptID = deptID; //TODO
            this.courseNum = courseNum; //TODO
            this.comparison = comparison; //TODO
            this.days = days; //TODO
            this.open = open; //TODO

            //SQL
            ResultsList();

        }

        private void ResultsList()
        {
            SqlConnection sqlCon = new SqlConnection(@"Data Source=DESKTOP-7S08N90;Initial Catalog=UniversityDB;Integrated Security=True");
            try
            {
                if (sqlCon.State == ConnectionState.Closed)
                    sqlCon.Open();
                //SQL query
                String query = "SELECT className AS [Class Name], section AS Section, room AS Room " +
                               "FROM Section " +
                               "WHERE semester=@Semester ";
                SqlCommand sqlCmd = new SqlCommand(query, sqlCon);
                sqlCmd.Parameters.AddWithValue("@Semester", this.semester);
                //sqlCmd.Parameters.AddWithValue("@Year", this.year);

                //Execute command and fill table with data
                SqlDataAdapter adapter = new SqlDataAdapter(sqlCmd);
                SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

                DataTable table = new DataTable();
                adapter.Fill(table);


                ResultsDataGrid.ItemsSource = table.DefaultView;
                ResultsDataGrid.AutoGenerateColumns = true;
                ResultsDataGrid.CanUserAddRows = false;
                ResultsDataGrid.CanUserSortColumns = true;

                sqlCmd.Dispose();
            }
            catch (Exception ex) //if SQL server connection fails
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                sqlCon.Close();
            }
        }

        private void bttnLogout_Click(object sender, RoutedEventArgs e)
        {
            Login login = new Login();
            login.Show();
            this.Close();
        }

        private void bttnBack_Click(object sender, RoutedEventArgs e)
        {
            MainWindow mainWindow = new MainWindow(studentID, semester, year);
            mainWindow.Show();
            this.Close();
        }

        private void preqCheck(SqlConnection con)
        {
            //TODO
        }

        private void bttnEnroll_Click(object sender, RoutedEventArgs e)
        {
            string className;
            string section;

            SqlConnection sqlCon = new SqlConnection(@"Data Source=DESKTOP-7S08N90;Initial Catalog=UniversityDB;Integrated Security=True");
            try
            {
                DataRowView row = (DataRowView)((Button)e.Source).DataContext;
                className = row[0].ToString();
                section = row[1].ToString();

                if (sqlCon.State == ConnectionState.Closed)
                    sqlCon.Open();

                preqCheck(sqlCon);

                //SQL query
                String query = "INSERT INTO Takes (studentID, className, section, semester, year, time, grade) " +
                               "SELECT @studentID, className, section, @semester, @year, time, @grade " +
                               "FROM Section " +
                               "WHERE className=@className " +
                               "AND section=@section";
                SqlCommand sqlCmd = new SqlCommand(query, sqlCon);
                sqlCmd.Parameters.AddWithValue("@studentID", this.studentID);
                sqlCmd.Parameters.AddWithValue("@className", className);
                sqlCmd.Parameters.AddWithValue("@section", section);
                sqlCmd.Parameters.AddWithValue("@semester", this.semester);
                sqlCmd.Parameters.AddWithValue("@year", this.year);
                sqlCmd.Parameters.AddWithValue("@grade", "N/A");

                int rowsAffected = sqlCmd.ExecuteNonQuery();
                if (rowsAffected == 1)
                {
                    MessageBox.Show("Class enrolled.");
                }
                else if (rowsAffected > 1)
                {
                    MessageBox.Show("More than 1 row affected");
                } else
                {
                    MessageBox.Show("Class not enrolled.");
                }
                sqlCmd.Dispose();
            }
            catch (Exception ex) //if SQL server connection fails
            {
                MessageBox.Show(ex.Message.ToString() + ". Class failed to enroll.");
            }
            finally
            {

                sqlCon.Close();
            }
        }
    }
}

【问题讨论】:

  • 看起来您插入的 select 语句正在抓取两行。尝试修复它,而不是插入。你可以通过SELECT TOP 1 破解这个(不推荐)。另外,不要使用AddWithValue
  • 两个具有基本相同布局的表格是一个糟糕的设计,因为您需要的只是另一列来表明......无论有什么区别(如果他们接受了?哪一年?)。它完全不需要这样的代码
  • @Zer0 啊,是的。谢谢。我认为 className 和 section 是唯一的,但事实证明并非如此。赞赏
  • @ŇɏssaPøngjǣrdenlarp,我知道,表格仍在整理中,但需要进行演示,所以我必须使用我所拥有的。我一定会在小组中提出来。
  • 看来你已经知道你的问题是什么了。问题是类名和部分可能不是唯一的。如果可能,您可以做出一个答案并将其标记为答案,以便其他人可以看到它。

标签: c# sql visual-studio


【解决方案1】:

@Zer0的回答:

看起来您插入的 select 语句正在抓取两行。尝试修复它,而不是插入。您可以通过执行 SELECT TOP 1 来破解这个(不推荐)。另外,不要使用 AddWithValue。

className 和 section 不足以成为唯一标识符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-17
    • 2012-10-08
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2021-02-17
    相关资源
    最近更新 更多