-1

I have a web page and there I have fields to hold some data.

One of the fields holds the IDs and names of students enrolled in a particular course. I want to be able to enroll new students to the course using a drop-down list. If the item selected in the drop-down list already exists in the Courses Table, I should display an error message.

I have a code to do these but when I select an already existing value in the drop-down list it doesn't show an error message. It assumes it's a new value and throws an exception because the Database doesn't accept duplicate records.

How can I solve this problem?

I use c# language to design this web page in ASP.NET.

    protected void DropDownList1_SelectedIndexChanged(object sender, 
    EventArgs e)
    {
        SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Ceng.mdf;Integrated Security=True");

        
        string qs = Request.QueryString["id"]; 
        // Variable qs Keeps CourseID retrieved from query string

        string sv = DropDownList1.SelectedItem.Value; 
        // Variable sv keeps selected value from DropDownList


        SqlCommand cmd = new SqlCommand("Select * from Enrolment as e, Students as s where e.StudentID = s.StudentID and " +
                          "CourseID = " + qs + " and StudentName = '" + sv +"'", con);
        // There are Students, Courses, and Enrolment tables in database
        // Students table columns are StudentID, StudentName, BirthDate
        // Course table columns are CourseID, CourseCode, CourseName, Instructor
        // Enrolment table columns are CourseID and StudentID


        con.Open();
        SqlDataReader reader = cmd.ExecuteReader();

        if(reader.HasRows)
        {
            Label1.Visible = true;
            Label1.Text = "The selected student is already registered to the course!";
            Label1.ForeColor = Color.Red;
        }
        else
        {
            Label1.Visible = true;
            Label1.Text = "The selected student is succesfully registered!";
            Label1.ForeColor = Color.Green;


            SqlDataSource4.Insert();
            GridView1.DataBind();
        }

        reader.Close();
        con.Close();
    }

When i select a name from DropDownList which is not exist in Database, i get proper result.

For example, Think about "Jeff Bezos" is already registered for given course. When i choose "Jeff Bezos" i should get error message but I get exception which says that is duplicate.

  • What is the runtime value of the `SELECT` query you're executing? Are there any matching rows? The described behavior suggests there are not. – David Apr 23 '19 at 11:09
  • For variable qs(value retrieved from Query String) 5, and DropDownList selected value Jeff Bazos there are 1 record that means record is exist. –  Apr 23 '19 at 11:14
  • what returned reader? – evilGenius Apr 23 '19 at 11:14
  • 2
    I would strongly suggest you alter your code to use parameters in the SQL not create a SQL statement directly from the UI values - avoid sql injection attacks. – Mark Schultheiss Apr 23 '19 at 11:15
  • @Ahmeett_: If a matching record exists then `reader.HasRows` is `true`. What exactly is the problem here? When you step through this line by line in your debugger, what specifically happens and where specifically does it fail? – David Apr 23 '19 at 11:15
  • What is the value of DropDownList for Jeff Bazos and StudentID for Jeff Bazos in database ? – Thamarai T Apr 23 '19 at 11:18
  • 1
    I would also consider an idisposable here for reference on a `using SqlConnection(...` for that https://stackoverflow.com/q/23185990/125981 – Mark Schultheiss Apr 23 '19 at 11:19
  • @David expected reader.HasRows is true but it returns false –  Apr 23 '19 at 11:20
  • @Ahmeett_: You're providing conflicting information. It seems that your assumptions do not match your observed results. So... drop the assumptions. If `reader.HasRows` is `false` then the reader has *no rows*. There are *no matching records*. So your query isn't what you expect it to be. So use your debugger and observe what your query *is*. What is it? What exact data is in your tables? Why do you expect something different? Elaborate. – David Apr 23 '19 at 11:21
  • @Thamarai T : Jeff Bezos an element of DropDownList as StudentName and his id is 1. –  Apr 23 '19 at 11:22
  • @David : SqlCommand cmd = new SqlCommand("Select * from Enrolment as e, Students as s where e.StudentID = s.StudentID and " + "CourseID = " + qs + " and StudentName = '" + sv +"'", con); –  Apr 23 '19 at 11:24
  • I mean, what is the output you are getting from `string sv = DropDownList1.SelectedItem.Value;` – Thamarai T Apr 23 '19 at 11:25
  • @David when i changed this like that -> SqlCommand cmd = new SqlCommand("Select * from Enrolment as e, Students as s where e.StudentID = s.StudentID and " + "CourseID = " + qs + " and StudentName = 'Jeff Bezos', con); then reader.HasRows is true –  Apr 23 '19 at 11:26
  • @ThamaraiT : output is Jeff Bezos –  Apr 23 '19 at 11:27
  • @Ahmeett_: That's not SQL code. That's C# code which dynamically *produces* SQL code. Clearly it's not producing the SQL code you expect it to produce. So the result you ***assume*** it is producing is incorrect. So ***stop assuming***. What is the ***actual SQL code being executed***. If you debug your code, we can help you. If all you want to do is insist that your code *should* be right and are looking for someone to agree with you, this isn't the right place for that. – David Apr 23 '19 at 11:27
  • Try this `SqlCommand cmd = new SqlCommand("Select * from Enrolment as e, Students as s where e.StudentID = s.StudentID and " + "CourseID = " + qs + " and **s.StudentName** = 'Jeff Bezos', con);` – Thamarai T Apr 23 '19 at 11:33
  • 1
    string qs = Request.QueryString["id"]; Prombel is here i fixed it. Id is an integer value but i choosed string. –  Apr 23 '19 at 11:49

2 Answers2

0
protected void DropDownList1_SelectedIndexChanged(object sender, 
    EventArgs e)
    {
        SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Ceng.mdf;Integrated Security=True");

        int selectedCourseId = 0;
        string qs = Request.QueryString["id"];        

        int.TryParse(qs, out selectedCourseId);

        string sv = DropDownList1.SelectedItem.Value;           

        SqlCommand cmd = new SqlCommand("Select * from Enrolment as e, Students as s where e.StudentID = s.StudentID and " +
                          "e.CourseID = @CourseID and s.StudentName = @StudentName", con);

        cmd.Parameters.Add("@CourseID", SqlDbType.Int).Value = selectedCourseId;
        cmd.Parameters.Add("@StudentName", SqlDbType.NVarChar).Value = sv;

        con.Open();
        SqlDataReader reader = cmd.ExecuteReader();

        if(reader.HasRows)
        {
            Label1.Visible = true;
            Label1.Text = "The selected student is already registered to the course!";
            Label1.ForeColor = Color.Red;
        }
        else
        {
            Label1.Visible = true;
            Label1.Text = "The selected student is succesfully registered!";
            Label1.ForeColor = Color.Green;


            SqlDataSource4.Insert();
            GridView1.DataBind();
        }

        reader.Close();
        con.Close();
    }
FalcoGer
  • 2,278
  • 1
  • 12
  • 34
Thamarai T
  • 252
  • 1
  • 6
  • 19
  • is there a reason why you select from 2 tables and build the whole cross instead of joining them? Also using * as a selector is bad practice. you should select only the rows you need for speed reasons.. – FalcoGer Apr 23 '19 at 12:13
0
  1. Parameterize the sql
  2. Make the sql a string/text and use it
  3. Get rid if bad associative join, create a INNER instead
  4. use a using which implements idisposable
  5. Assumptions since you did not post the source of the list
  6. Broad assumption on the int vs string for id (int is most common so I go with that)
  7. Suggest this might be refactored to methods for better testing
       using System;
       using System.Data.SqlClient;
        // more here likely...
        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string connectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Ceng.mdf;Integrated Security=True";
            string getStudentIdSql = @"
                SELECT s.StudentID 
                FROM Enrolment AS e
                INNER JOIN Students AS s 
                    ON e.StudentID = s.StudentID 
                    AND E.CourseID = @CourseID
                    AND StudentName = @StudentName
            ";
            int courseId = int.Parse(Request.QueryString["id"]); // consider tryparse here, I make assumptions on the int also
            // string studentName = DropDownList1.SelectedItem.Value; // assumption if the values are there
            string studentName = DropDownList1.SelectedItem.Text; // assumption based on code/comments, key part where it is defined is missing from question
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = new SqlCommand(getStudentIdSql, conn))
                {
                    cmd.Parameters.Add("@CourseID", SqlDbType.Int).Value = courseId;
                    cmd.Parameters.Add("@StudentName", SqlDbType.VarChar, 80).Value = studentName;
                    SqlDataReader reader = cmd.ExecuteReader();
                    if (reader.HasRows)
                    {
                        /* if we wanted to have the rows
                    while (reader.Read())
                    {
                        Console.WriteLine($"{reader.GetInt32(0)}\t{ reader.GetString(1)}");
                    }
                    */
                        Label1.Visible = true;
                        Label1.Text = "The selected student is already registered to the course!";
                        Label1.ForeColor = Color.Red;
                    }
                    /* basic thing
                else
                {
                    Console.WriteLine("No rows found.");
                }
                */
                    else
                    {
                        Label1.Visible = true;
                        Label1.Text = "The selected student is succesfully registered!";
                        Label1.ForeColor = Color.Green;
                        SqlDataSource4.Insert();
                        GridView1.DataBind();
                    }

                    reader.Close();
                }
            }
        }
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100