0

I've two tables company with CompanyID {auto increment primary key} and group with GroupID {auto increment primary key}. In the group table I want to insert group details on submit button click along with updating company table's groups column with the GroupID just inserted in group table. Please suggest me how should I do this either with separate commands or through stored procedure. I'm little bit weak with SQL server queries so need some help with explanation. What am I doing wrong it gives "Incorrect syntax near the keyword 'inner'". Thanks in advance.

Company table

Group table

Submit button on web form

Submit button click code:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    string group = GroupName.Text;
    string dept = Department.Text;
    string company = Session["com"].ToString();

    if ((HttpContext.Current.User != null) && HttpContext.Current.User.Identity.IsAuthenticated && company != null)
    {
        string strcon = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;
        SqlConnection con = new SqlConnection(strcon);
        con.Open();
        DataSet ds = new DataSet();
        SqlDataReader rdr = null;
        SqlCommand cmd1 = new SqlCommand("Insert into Group(GroupName, Department, CompanyID) Values(@groupName, @department, 'Select CompanyID from Company1 where Company.CompanyName=@companyName')", con);
        SqlCommand cmd = new SqlCommand("Update Company1 set Company1.Groups=Group.GroupID inner join Group on Group.CompanyID=Comapny1.CompanyID"
                        +" where Company.CompanyName=@companyName", con);
        cmd1.Parameters.Add("@groupName", SqlDbType.NVarChar).Value = group;
        cmd1.Parameters.Add("@department", SqlDbType.NVarChar).Value = dept;
        cmd1.Parameters.Add("@companyName", SqlDbType.NVarChar).Value = company;
        cmd.Parameters.Add("@companyName", SqlDbType.NVarChar).Value = company;
        //cmd1.Parameters.AddWithValue("@groupName", group);
        //cmd1.Parameters.AddWithValue("@department", dept);
        //cmd.Parameters.AddWithValue("@companyName", company);

        rdr = cmd1.ExecuteReader();
        rdr = cmd.ExecuteReader();
        con.Close();
    }
    else
    {
        Response.Redirect("Account/Login.aspx");
    }
}
Rashid
  • 105
  • 1
  • 11
  • 1
    You should check out [Can we stop using AddWithValue() already?](http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/) and stop using `.AddWithValue()` - it can lead to unexpected and surprising results... – marc_s Oct 09 '14 at 09:11
  • Is `Groups.CompanyID` a foreign key to `Company1.CompanyID`? If so what does `Company21Groups` contain? If it needs to be the GroupID just inserted why is it `NVARCHAR(30)` when `GroupID` is an `INT`? – GarethD Oct 09 '14 at 09:21
  • Chang your update query to below "Update Company1 set Company1.Groups=Group.GroupID inner join Group on Group.CompanyID=Comapny1.CompanyID " +" where Company.CompanyName=@companyName" – vallabha Oct 09 '14 at 09:30
  • Thanks all. I applied all your suggestions but it did not work, the error now is "Incorrect syntax near the keyword 'Group'". Any help using procedures? @GarethD the GroupID in company is taken as NVARCHAR(30) to facilitate multiple GroupIDs separated by comma, how can I achieve this any idea? – Rashid Oct 09 '14 at 10:29
  • Here we have the UI, the view, the business logic and the data layer, all in one function! – frenchie Oct 09 '14 at 10:44
  • @frenchie I did not get you what you suggest. – Rashid Oct 09 '14 at 11:07
  • I suggest breaking down this function so that when the click handler triggers, it instantiate an object in another class that handles the work. Something like this: "if (HttpContext.Current....) { new PageWorkerObject().ExecuteDatabaseMagic(); } That way the class that defines PageWorkerObject is in a different file and reusable in other pages. – frenchie Oct 09 '14 at 11:10

1 Answers1

1

With reference to this comment:

the GroupID in company is taken as NVARCHAR(30) to facilitate multiple GroupIDs separated by comma, how can I achieve this any idea?

The answer is don't. You are duplicating data, storing relationships as a delimited string is never a good idea in a relational database. It defeats the purpose.

I think all you need to do is insert the CompanyID at the same time as inserting the group:

INSERT dbo.Group (GroupName, Department, CustomerID)
SELECT  @GroupName, @Department, c.CompanyID
FROM    dbo.Company1 AS c
WHERE   c.CustomerName = @CustomerName;

So your c# would end up looking like:

string sql = @"INSERT dbo.[Group] (GroupName, Department, CustomerID)
                SELECT  @GroupName, @Department, c.CompanyID
                FROM    dbo.Company1 AS c
                WHERE   c.CompanyName = @CompanyName;";
string strcon = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;

using (var connection = new SqlConnection(strcon))
using (var command = new SqlCommand(sql, connection))
{
    connection.Open();
    command.Parameters.Add(@GroupName, SqlDbType.NVarChar, 50).Value = group;
    command.Parameters.Add(@Department, SqlDbType.NVarChar, 50).Value = dept;
    command.Parameters.Add(@CompanyName, SqlDbType.NVarChar, 50).Value = company;
    command.ExecuteNonQuery();
}

Note the use of ExecuteNonQuery() instead of ExecuteReader() since you aren't actually reading anything, and the use of using blocks to ensure your objects are disposed of correctly. I have also included the schema prefix in your queries (assumed to be dbo) as it is usually a good idea to include this as standard

If you need to get the groups associated with a particular company do this in a query to avoid recalculating the Groups column with every INSERT/UPDATE/DELETE:

SELECT  c.CompanyID,
        c.CompanyName,
        Groups = STUFF((SELECT ',' + CAST(g.GroupID AS VARCHAR(10))
                        FROM    dbo.[Group] AS g
                        WHERE   g.CompanyID = c.CompanyID
                        FOR XML PATH(''), TYPE
                        ).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM    dbo.Company AS c;

For more information on concatenating rows into a column see this answer;

Community
  • 1
  • 1
GarethD
  • 68,045
  • 10
  • 83
  • 123
  • Wow, thanks @GarethD the insert query worked like charm but when I applied the same approach with update like: string updateSql = @"Update dbo.[Company1] SET Company1.Groups = g.GroupID FROM dbo.[Group] AS g WHERE Company1.CompanyName='BNK' AND g.CompanyID=Company1.CompanyID;";. The query ran but with no effect. Any suggestions. – Rashid Oct 09 '14 at 12:47
  • Why do you need to store GroupID against `Company`? This link already exists since the `Group` table has a column `CompanyID`, What should show in the `Groups` in Company if there is more than one group that relates to the company? How are you going to maintain it if someone updates `CompanyID` in `Group`? This would then need to update two records in `Company`. As explained this is not a good approach and rather than wasting time trying to figure out how to jam a square peg into a round hole, I would get a different peg! – GarethD Oct 09 '14 at 13:18
  • Oooo now I got your point. Yes you are right I don't need the extra Groups column in Company1 table. Thanks for your clarification sir. You rock!! – Rashid Oct 09 '14 at 13:40