4

In the following sample, I build a query to do a bulk insert into a MySQL database:

const string QUERY = "INSERT INTO contacts (first_name,last_name) VALUES{0};";

public string BuildQuery(IEnumerable<contact> contacts)
{
    List<string> values = new List<string>();

    foreach (var contact in contacts)
    {
        values.Add(string.Format("('{0}','{1}')", contact.first_name, contact.last_name));
    }

    return string.Format(QUERY, string.Join(",", values));
}

The result might look something like this:

INSERT INTO contacts (first_name,last_name) VALUES("J","Kappers"),("A","Temple")

What can I do to write a safer query that isn't prone to SQL Injection?

Kappers
  • 1,341
  • 3
  • 15
  • 26
  • Use Stored procedure in mysql and pass the values in this function. – Romil Kumar Jain Jun 25 '12 at 13:09
  • Thanks for the suggestion, Romil! Unfortunately, using a stored proc is not an option for me. Hoping for a different solution. – Kappers Jun 25 '12 at 13:12
  • 1
    @Kappers you can construct MysqlCommand parameters instead of query itself. See this link for an answer http://stackoverflow.com/a/10191104/661933 – nawfal Jun 25 '12 at 13:41

2 Answers2

1
const string QUERY = "INSERT INTO contacts (first_name,last_name) VALUES" + 
                      BuildQuery(c, contacts);

public string BuildQuery(MySQLCommand c, IEnumerable<contact> contacts)
{
    List<string> values = new List<string>();
    string query = null;
    int i = 0;
    foreach (var contact in contacts)
    {
       i++;
       query += "(@firstName" + i + ", @lastName" + i + ")";
       c.Parameters.AddWithValue("@firstName" + i, contact.first_name);
       c.Parameters.AddWithValue("@lastName" + i, contact.last_name);

       if(i < contacts.Count) 
          query += ",";
    }

    return query
}

You can see a relevant thread here!. I must have missed somethin trivial, but thats trivial for u to fix. Of course you know what happens when contacts has no elements. I dont see more edge cases. Btw, mind u there is a limit to how many such parameters you can add depending on mysql's max allowed packet size. You can change it, or take care of not exceeding that limit. Cheers! :)

Community
  • 1
  • 1
nawfal
  • 70,104
  • 56
  • 326
  • 368
-1

You can escape your MySQL command arguments almost the same way as in normal SQL command. Here is example from official MySQL manual

 private void PrepareExample()
 {
     MySqlCommand cmd = new MySqlCommand("INSERT INTO mytable VALUES (?val)", myConnection);
     cmd.Parameters.Add( "?val", 10 );
     cmd.Prepare();
     cmd.ExecuteNonQuery();

     cmd.Parameters[0].Value = 20;
     cmd.ExecuteNonQuery();
 }

P.S. Whatever you choose - never user string manipulation to add/insert parameters to SQL command. This is main source for SQL-Injections attacks

Alex F
  • 3,180
  • 2
  • 28
  • 40