I've developed a method that allows me to pass in a table (string), array of columns (string) and array of values (object) through the parameters which I then use to create a parameterized query. Although it works fine the length of the code as well as the multiple for loops gave off a code smell, in particular I feel the method I use to insert a comma between the columns and values can be done a different and better way.
public static int Insert(string source, string[] column, object[] values)
{
int rowsAffected = 0;
try
{
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
StringBuilder query = new StringBuilder();
query.Append(" INSERT INTO ");
query.Append(source);
query.Append("(");
for (int i = 0; i < column.Length; i++)
{
query.Append(column[i]);
if (i < values.Length - 1)
{
query.Append(",");
}
}
query.Append(")");
query.Append(" VALUES ");
query.Append("(");
for (int i = 0; i < values.Length; i++)
{
query.Append("@" + values[i].ToString());
if (i < values.Length - 1)
{
query.Append(",");
}
}
query.Append(")");
conn.Open();
using (SQLiteCommand cmd = new SQLiteCommand(query.ToString(), conn))
{
for (int i = 0; i < values.Length; i++)
{
cmd.Parameters.AddWithValue("@" + values[i].ToString(), values[i]);
}
rowsAffected = cmd.ExecuteNonQuery();
}
}
return rowsAffected;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
return 0;
}
I'm using the System.Data.SQLite library to interact with the database.
Thanks for any suggestions!
This is my idiomatic way to append multiple values with a separator using StringBuilder:
This assumes you will have at least one value, and usually where I use it, it would be an error not to have at least one value (and it appears your scenario is like that).
It also appears that you have left this code wide open for SQL Injection.
You seem to be trying to use parameters, but I don't think you've done it correctly. The way I read the code, you are using the actual value of the parameters instead of their index. I would suggest this modification (this assumes your array of column names comes from a trusted source, but that your values do not):
The number of parameters and values has to always be the same for this to work, so you could eliminate a loop by using two StringBuilders. (Untested code, but it should get the point across)
Since the lengths are the same you can build the parameter list and the value list at the same time, and then just stick the value list in the appropriate spot at the end of the loop. Net result should be faster. :)
Here is another option. Really doing the same thing your original code does but breaking it up into smaller chunks and abstracting it into a class called InsertBuilder.
Then your original code looks something like this.