Reputation: 269
I posted about a different issue I had earlier, and with some help resolved that.
I am now receiving a syntax error centered around the following code:
importConnection.Open();
Console.WriteLine("Foxpro connection open");
OleDbCommand deleteOleDbCommand = new OleDbCommand(@"TRUNCATE TABLE CLIENT",
importConnection);
Console.WriteLine("writing to table");
Console.ReadKey();
using (OleDbCommand importCommand = new OleDbCommand(
string.Format("INSERT INTO CLIENT (Title,Fname,Sname)" + "VALUES ({0},{1},{2})",
exportReader.GetValue(0), exportReader.GetValue(1), exportReader.GetValue(2))))
importCommand.ExecuteReader();
With this being the output:
using break points I have determined that the export reader calls are receiving data. I've narrowed it down to an issue with:
"VALUES ({0},{1},{2})",
exportReader.GetValue(0), exportReader.GetValue(1), exportReader.GetValue(2))))
I have confirmed that data can be inserted by doing the following:
using (OleDbCommand importCommand =
new OleDbCommand(string.Format(
"INSERT INTO CLIENT (Title,Fname,Sname)" + "VALUES (Mr,Joshua,Cameron-Mackintosh)",
importConnection)))
This causes no problems, so I know the issue does not lie with the underlying connection or command.
Upvotes: 0
Views: 901
Reputation: 133
You must give space to your concatenated strings.
"INSERT INTO CLIENT (Title,Fname,Sname)" + "[space here]VALUES (Mr,Joshua,Cameron-Mackintosh)"
however, it should look like this:
"INSERT INTO CLIENT (Title,Fname,Sname) VALUES (?,?,?)"
Always make use of parametrized queries. Please refer to: http://blogs.technet.com/b/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx
Upvotes: 0
Reputation: 48139
Others correctly comment about SQL-Injection, however VFP is less impacted to SQL-Injection, it can be just the same. Main reason, VFP doesn't really work with multiple queries the same way other sql engines allow by a ";" identifying break between statements. However, with mismatched quotes, it CAN and WILL break your sql-statements from actually running.
Having said that, VFP OleDb provider does allow parameterizing, but does so without "named" parameters. It does it with "?" as a place-holder for where the value would be inserted by the .net framework, and you don't have to convert the data type as long as it is in the same expected format (ex: string, numeric, date)
change your OleDbCommand to
"INSERT INTO CLIENT (Title, Fname, Sname ) values ( ?, ?, ? )"
Then, set your parameters via
importCommand.Parameters.Add( "parmForTitle", exportReader.GetValue(0));
importCommand.Parameters.Add( "parmForFName", exportReader.GetValue(1));
importCommand.Parameters.Add( "parmForSName", exportReader.GetValue(2));
Also, the parameters must be added in the exact same sequential order as they appear in the query. So, I prefixed them with "parmFor" to indicate it is the parameter placement for the corresponding field being inserted (or updated, or used in select, insert or delete too). The command objects work the same for all the commands. Even if you write a select statement and have values in a WHERE, JOIN or whatever other position.
THEN, ExecuteNonQuery()
Upvotes: 3
Reputation: 23797
A revised version of your code would then be:
importConnection.Open();
Console.WriteLine("Foxpro connection open");
OleDbCommand deleteOleDbCommand = new OleDbCommand(@"Delete from CLIENT",
importConnection);
Console.WriteLine("writing to table");
Console.ReadKey();
using (OleDbCommand importCommand = new OleDbCommand(
@"INSERT INTO CLIENT (Title,Fname,Sname) VALUES (?,?,?)",
importConnection))
{
importCommand.Parameters.AddWithValue("title","");
importCommand.Parameters.AddWithValue("fname","");
importCommand.Parameters.AddWithValue("sname","");
// maybe in a loop here
importCommand.Parameters["title"].Value = exportReader.GetValue(0);
importCommand.Parameters["fname"].Value = exportReader.GetValue(1);
importCommand.Parameters["sname"].Value = exportReader.GetValue(2);
importCommand.ExecuteNonQuery();
// ...
}
PS: You could directly feed the values on the Parameters.AddWithValue instead of creating a separate .Parameters["..."].Value = ... but then you would only be able to do that for a single insertion (not something related to VFP, it is the case for OleDb or Sql or whatever).
Upvotes: 1
Reputation: 98740
You don't need ExecuteReader
for an insert statement. Just use ExecuteNonQuery
.
In your case, if your columns are character typed, you need to use single quotes with them for example;
VALUES ('{0}', '{1}', '{2}')
Also use white space (not have to but as a good practice) before VALUES
part.
"INSERT INTO CLIENT (Title,Fname,Sname)" + " VALUES (Mr,Joshua,Cameron-Mackintosh)",
// ^^^ here
You should always use parameterized queries. Prepared statements automatically handle for escape characters for example and this kind of string concatenations are open for SQL Injection attacks.
Upvotes: 0