Reputation: 602
I'm building a SQL update statement based on which check-boxes where selected for each field to update. I'm running into trouble syntax wise with my statement because certain parameters are optional. For example, if the user was to just select the Location check-box, the statement would execute perfectly because only one of the columns is updated:
UPDATE [Group] SET Location = @p_Location WHERE GroupID = @p_GroupID
However, if the user selects more than one column to update then I have a problem syntax wise because I cannot control the commas after the parameters since they could be in any order
var sql = new StringBuilder();
sql.Append(@"UPDATE [Group] SET ");
if (updateModel.IsUseGroupNumberSelected)
{
sql.Append("GroupNumber = @p_GroupNumber");
cmd.Parameters.AddWithValue("@p_GroupNumber", updateModel.Group.GroupNumber);
}
if (updateModel.IsUseTerminationDateSelected)
{
sql.Append("GroupNumber = @p_GroupNumber");
cmd.Parameters.AddWithValue("@p_TerminationDate", updateModel.Group.TerminationDate);
}
if (updateModel.IsUseLocationSelected)
{
sql.Append("Location = @p_Location");
cmd.Parameters.AddWithValue("@p_Location", updateModel.Group.Location);
}
sql.Append(" WHERE GroupID = @p_GroupID");
cmd.Parameters.AddWithValue("@p_GroupID", updateModel.Group.GroupID);
Does anyone have any ideas on how to combat this? I was thinking about looping through the SQL string and adding an extra comma where needed but it seems less secure and messy. Thought I should pick the minds of the brillent stackoverflow first. Thanks for your help!
Upvotes: 1
Views: 9597
Reputation: 3060
A little bit of boolean logic is all you need to add to make it work like you want. The key is to only add the comma when you are not the first to add a column to update.
Bool first = true;
var sql = new StringBuilder();
sql.Append(@"UPDATE [Group] SET ");
if (updateModel.IsUseGroupNumberSelected)
{
if (!first) sql.Append(", ");
sql.Append("GroupNumber = @p_GroupNumber");
cmd.Parameters.AddWithValue("@p_GroupNumber", updateModel.Group.GroupNumber);
first = false;
}
if (updateModel.IsUseTerminationDateSelected)
{
if (!first) sql.Append(", ");
sql.Append("TerminationDate = @p_TerminationDate");
cmd.Parameters.AddWithValue("@p_TerminationDate", updateModel.Group.TerminationDate);
first = false;
}
if (updateModel.IsUseLocationSelected)
{
if (!first) sql.Append(", ");
sql.Append("Location = @p_Location");
cmd.Parameters.AddWithValue("@p_Location", updateModel.Group.Location);
first = false;
}
sql.Append(" WHERE GroupID = @p_GroupID");
cmd.Parameters.AddWithValue("@p_GroupID", updateModel.Group.GroupID);
Upvotes: 2
Reputation: 35318
You could wait until the end to add the beginning of the query:
private void DoStuff()
{
AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
var sql = new StringBuilder();
if (updateModel.IsUseGroupNumberSelected)
{
AppendCommaIfNeeded(sql);
sql.Append("GroupNumber = @p_GroupNumber");
cmd.Parameters.AddWithValue("@p_GroupNumber", updateModel.Group.GroupNumber);
}
if (updateModel.IsUseTerminationDateSelected)
{
AppendCommaIfNeeded(sql);
sql.Append("GroupNumber = @p_GroupNumber");
cmd.Parameters.AddWithValue("@p_TerminationDate", updateModel.Group.TerminationDate);
}
if (updateModel.IsUseLocationSelected)
{
AppendCommaIfNeeded(sql);
sql.Append("Location = @p_Location");
cmd.Parameters.AddWithValue("@p_Location", updateModel.Group.Location);
}
sql.Insert(0, @"UPDATE [Group] SET ");
sql.Append(" WHERE GroupID = @p_GroupID");
cmd.Parameters.AddWithValue("@p_GroupID", updateModel.Group.GroupID);
}
private void AppendCommaIfNeeded(StringBuilder toBuilder)
{
if (toBuilder.Length > 0) toBuilder.Append(",");
}
Upvotes: 1
Reputation: 11514
Create your update statement with all the parameters, then use COALESCE
to ignore the parameters that were not set.
UPDATE [Group]
SET Location = COALESCE(@p_Location, [Location]),
GroupNumber = COALESCE("@_GroupNumber", [GroupNumber]),
... etc
You can do that in the WHERE clause also if you need to dynamically filter.
Upvotes: 1
Reputation: 8485
Track the additional queries in a List<string>
. You can join them with a comma after you have them all in a list:
https://dotnetfiddle.net/LtIhW8
List<string> whereClauses = new List<string>();
for(int i = 0; i < 10; i++){
whereClauses.Add("where Clause " + i.ToString()) ;
}
sql.Append(string.Join(",", whereClauses));
Upvotes: 0