0

I want to use Windows Forms and C# to implement a Database application which consists of the following tables:

Student table:

CREATE TABLE [dbo].[Student] 
(
    [Id]   INT          NOT NULL,
    [Name] NVARCHAR(50) NOT NULL,
    [MyId] AS ('S' + RIGHT('00' + CONVERT([varchar](5), [Id]), (2))) PERSISTED,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

Class table:

CREATE TABLE [dbo].[Class] 
(
    [Id]      INT          NOT NULL,
    [Teacher] NVARCHAR(50) NOT NULL,
    [Grade]   INT          NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

StudentClassCombo:

CREATE TABLE [dbo].[StudentClassCombo]  
(
    [ClassID]   INT NOT NULL,
    [StudentID] INT NOT NULL,
    CONSTRAINT [ClassFK] 
        FOREIGN KEY ([ClassID]) REFERENCES [dbo].[Class] ([Id]),
    CONSTRAINT [StudentFK] 
        FOREIGN KEY ([StudentID]) REFERENCES [dbo].[Student] ([Id])
);

I have a Windows forms interface through which I can assign students to classes.

enter image description here

I want to ensure that when the a student that has already been assigned to a class is re-assigned to a different class. the previous student-class assignment should be overwritten with the new one. In the case above, if Student ID 1 is already assigned to Class ID 1. But if the user decides to re-assign Student ID 1 to Class ID 2, the existing StudentClassCombo entry of 1-1 should be changed to 1-2.

I have written the following code to perform this update but I am encountering an exception:

string UpdateQuery = @"UPDATE dbo.StudentClassCombo SET"
                      + " Class.ID as ClassId, Student.Id as StudentId FROM dbo.Class, dbo.Student" +
                      " WHERE Class.Grade=@Grade and Student.Name LIKE @StudentName";


using (connection = new SqlConnection(connectionString))
using (SqlCommand Insertcmd = new SqlCommand(UpdateQuery, connection))
{
    connection.Open();

    Insertcmd.Parameters.Add("@Grade", SqlDbType.Int);
    Insertcmd.Parameters.Add("@StudentName", SqlDbType.NVarChar, 50);

    foreach (ListViewItem eachItem in StudentsList.CheckedItems)
    {
        Insertcmd.Parameters["@Grade"].Value = int.Parse(ClassNames.Text);
        Insertcmd.Parameters["@StudentName"].Value = eachItem.SubItems[1].Text.ToString();
                    
        Insertcmd.ExecuteNonQuery();
    }

    connection.Close();
}

The exception I am seeing now is as follows:

An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll

Additional information: Incorrect syntax near the keyword 'as'.

How should I update the StudentClassCombo entries?

5
  • In a TSQL update statement you set column values with =, not as. Are you sure that UpdateQuery is what you want to execute for Insertcmd? Commented Jul 8, 2021 at 19:42
  • Be careful saying "is assigned to a different class at another time" as it's confusing/ambiguous between whether the time means the "scheduled start time of the class" ie 1pm every Tuesday, or "the moment at which the student is assigned to a class" ie the user clicked the save button at 3:47pm on Jan 1 2021 Commented Jul 8, 2021 at 20:01
  • @HABO Thank you for the response. Are you sure that UpdateQuery is what you want to execute for Insertcmd? You are right...it isn't correct Commented Jul 8, 2021 at 20:06
  • @CaiusJard Thank you for the response. I shall update my question. Commented Jul 8, 2021 at 20:07
  • 1
    As per the question guide, please do not post images of code, data, error messages, etc. - copy or type the text into the question. Please reserve the use of images for diagrams or demonstrating rendering bugs, things that are impossible to describe accurately via text. Commented Jul 8, 2021 at 21:22

1 Answer 1

2

You should first executenonquery this:

UPDATE StudentClassCombo SET ClassId = @ClassId WHERE StudentId =@StudentId

..and capture the return value from ExecuteNonQuery

If the return value is 0, no records were updated (there is no student with that ID), run the following insert instead:

INSERT StudentClassCombo (ClassId,StudentId) VALUES(@ClassId,@StudentId)

You seem to already know how to add parameters to sql commands etc so I'll skip that part

Put a unique index on StudentId

If Class:Student is 1:Many (as you imply) it would be more typical to put ClassId as a column of Student table than have a middleman table, unless that middle table stores other relevant data than just the class and student id

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you for the answer. ClassId and StudentId belong to separate tables for me. Wouldn't I need a subquery to obtain assignments of ClassId and StudentId?
Your front end app should know the ID; you should e.g. SELECT CONCAT(Grade, ' - ', Teacher) as ClassName, Id FROM Class and load that into a datatable, set the Combo.DataSource = theDatatable and set the DisplayMember to "ClassName" and the ValueMember to "ID".. Now your user sees "Beta = 11" in the combo but when they pick it, you can ask the combo for classCombo.SelectedValue and it will be "1" which is the ID of the Class, for insert/update into StudentClassCombo.
In short: make sure the app downloads both the ID and the name, show the user the name and use the relevant ID they pick. Controls like combos have ways of specifying "show this column, but when I asked for the selected value, give me that other column"
I have this code when I am populating the combo-box: ClassNames.DisplayMember = "Grade"; ClassNames.ValueMember = "Id";
Sounds like you're on the right track then. Just ask for the SelectedValue if you want the ID. Set the style to DropDownList too
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.