I am using the INSERT ... SELECT syntax to select existing rows from a table and insert then into another table. In addition to the existing data from each row I also need to add a BillingID and TimeStamp. Because these fields are in the SELECT part of the SQL statement I cannot parametrize them. I solved the TimeStamp issue using the SQL function NOW(), however I am still left with BillingID which I have added to the query via sting concatenation as follows:
static void UpdateMonthlyData(int BillingID, DateTime HistoryDate, int CompanyID)
{
String conString = ConfigurationManager.ConnectionStrings["xxx"].ConnectionString;
MySqlConnection connection = new MySqlConnection(conString);
String command = "INSERT INTO MonthlyData SELECT " + BillingID + ", d.*, NOW() "
+ "FROM CurrentData d WHERE d.CompanyID = @CompanyID AND d.HistoryDate = @HistoryDate";
MySqlCommand cmd = new MySqlCommand(command, connection);
cmd.Parameters.Add(new MySqlParameter("@CompanyID", CompanyID));
cmd.Parameters.Add(new MySqlParameter("@HistoryDate", HistoryDate));
cmd.CommandType = CommandType.Text;
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
}
I am not concerned with SQL Injection as this is a console app that is run on an automated schedule and has no user interaction whatsoever. (BillingID is auto-generated). Despite that, I don't like using concatenated strings as they are not very readable. Is there a more elegant way of doing this?
Edit:
To sum things up, I thought that since since you cant do this:
SELECT @field FROM @table
I presumed that parameters are not allowed in the SELECT part of a SQL statement. However since I am specifying a value in the select statement rather than selecting a column, as @cdhowie pointed out I can use a parameter there. In essence my query translated is something like this:
SELECT 25 FROM table_name, not SELECT field FROM table_name
So now thanks to @cdhowie I understand that a parameter can be anywhere a literal value can be