SqlCommand SQL вставка с ExecuteNonQuery вставкой 2 строки - PullRequest
0 голосов
/ 12 марта 2020

У меня есть кнопка в таблице, которая вызывает оператор вставки,

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();
            }
        }
    }
}

1 Ответ

0 голосов
/ 06 апреля 2020

@ Zer0 :

Похоже, оператор select, из которого вы вставляете, захватывает две строки. Попробуйте исправить это, а не вставку. Вы можете взломать это (не рекомендуется), выполнив SELECT TOP 1. Кроме того, не используйте AddWithValue.

className и section не были достаточны, чтобы быть уникальным идентификатором.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...