As the past says, you cannot pass the column name to an OleDB SQL query as a parameter. Parameters only for values, not table or column names.
As failed passed attempts mention in their comments, this is not secure - since this could be dangerous. The main problem is if the table name comes from user input - if it is so, it will leave an SQL injection vulnerability in your application.
Thus, if it does indeed come from user input you'll need to protect yourself. The easiest way is to make sure that table name is a valid table, Attached table, or query name - To do that, you can use a query like so:
SELECT Name FROM Myssobjects Where Type in (1,5,6,)
This query will return you the valid values for tables in your database, which you can compare to the input you got. Notice you should still use this with caution, because most of the times you won't want to let your user have access to your entire database.
Anyhow, if you protected yourself well and made sure that you are no longer vulnerable, the way to do this is dynamically create the string for the query - like so:
string tableName = value;
string query = "INSERT INTO t1 select "+tableName+",c2 FROM t2 WHERE c3= $v2";
SqlCommand cmd= new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("$v2", data);
// etc. - instead of the AddWithValue(), you add it to the string.
EDIT: Since this isn't exacly what you asked for, I'll explain what I mean in relation to your pseudo code:
$insertv1=$v1
$insertv2= select c2 from t2 where c3=$v2
query = insert INTO t1 VALUES ($insertv1,$insertv2)
Would actually require seperation of the two queries, and thus translate into:
string v1="Your value here.",v2="Your second value here.",v3="";
//first : get v2.
SqlCommand cmd= new SqlCommand("select c2 from t2 where c3=$v2", conn); // using the v2 query you stated.
cmd.Parameters.AddWithValue("$v2", v2);
cmd.ExecuteNonQuery();
// put the value from the query into v3
// then, make the entire, bigger query
string finalQuery = "INSERT INTO t1 VALUES($v1,$v2)";
SqlCommand cmd2= new SqlCommand(finalQuery, conn);
cmd2.Parameters.AddWithValue("$v1", v1);
cmd2.Parameters.AddWithValue("$v2", v3);
cmd2.ExecuteNonQuery();
Note that deparameterizing the values $v1 and $v2 solves the problem but just parameterizing one of the two causes a problem.
EDIT 2:
In chat, we looked further into the compliation error, since there was some strange behavior with parameterizing different values. I asked you what values are in $v1
and $v2
, and we figured that the nvarchar
in v2
is misinterpreted as a pseudo name. That also explains why the SQL works but the C# failed; the error was in fact in the way OleDB intrepreted the name. The solution is simple - add '
marks before and after v2,
which will lead to it being read as a non-pseudo string, like so: "INSERT INTO t1 select $v1,c2 FROM t2 WHERE c3= '$v2'"
.