1

I keep getting an error when I attempt to insert values into a Access database.

The error is syntactic, which leads to the following exception:

OleDbException was unhandled Syntax error in INSERT INTO statement.

private OleDbConnection myCon;

public Form1()
{
    InitializeComponent();
    myCon = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\File.mdb");
}

private void insertuser_Click(object sender, EventArgs e)
{
    OleDbCommand cmd = new OleDbCommand();
    myCon.Open();
    cmd.Connection = myCon;
    cmd.CommandType = CommandType.Text;

    cmd.CommandText = "INSERT INTO User ([UserID], [Forename], [Surname], " +
                                        "[DateOfBirth], [TargetWeight], [TargetCalories], [Height]) " +
                      "VALUES ('" + userid.Text.ToString() + "' , '" +
                                    fname.Text.ToString() + "' , '" +
                                    sname.Text.ToString() + "' , '" +
                                    dob.Text.ToString() + "' , '" +
                                    tarweight.Text.ToString() + "' , '" +
                                    tarcal.Text.ToString() + "' , '" +
                                    height.Text.ToString() + "')";

    cmd.ExecuteNonQuery();
    myCon.Close();
}
Shin
  • 664
  • 2
  • 13
  • 30
Howard
  • 41
  • 1
  • 3
  • 6
  • 2
    Can you post the error you are receiving? – nabrond Jan 07 '11 at 16:15
  • 1
    are you getting an exception? Is the application crashing? Enclose the statements in a try..catch block, catch the exception and post the exception message. – Devendra D. Chavan Jan 07 '11 at 16:17
  • Hi this is the exception message: Syntax Error in INSERT INTO statement OleDbException was unhandled – Howard Jan 07 '11 at 16:46
  • I don't work in C#, so don't know how it interacts with your database interface layer, but Jet/ACE uses `#` as the delimiter for the string representation of date values, not `'`. Changing that might help. At the very least, write out the SQL string being sent and see if you can run it in interactive Access. – David-W-Fenton Jan 08 '11 at 03:33

6 Answers6

8

Well, you haven't specified what the error is - but your first problem is that you're inserting the data directly into the SQL statement. Don't do that. You're inviting SQL injection attacks.

Use a parameterized SQL statement instead. Once you've done that, if you still have problems, edit this question with the new code and say what the error is. The new code is likely to be clearer already, as there won't be a huge concatenation involved, easily hiding something like a mismatched bracket.

EDIT: As mentioned in comments, Jet/ACE is vulnerable to fewer types of SQL injection attack, as it doesn't permit DML. For this INSERT statement there may actually be no vulnerability - but for a SELECT with a WHERE clause written in a similar way, user input could circumvent some of the protections of the WHERE clause. I would strongly advise you to use parameterized queries as a matter of course:

  • They mean you don't have to escape user data
  • They keep the data separate from the code
  • You'll have less to worry about if you ever move from Jet/ACE (whether moving this particular code, or just you personally starting to work on different databases)
  • For other data types such as dates, you don't need to do any work to get the data into a form appropriate for the database

(You also don't need all the calls to ToString. Not only would I expect that a property called Text is already a string, but the fact that you're using string concatenation means that string conversions will happen automatically anyway.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    @Howard: With no more detail than that? Oh well - that's still better than not even knowing that much. When your SQL is parameterized, it may well be easier to see the problem - or it may just go away anyway, if the error was due to your data containing quotes. – Jon Skeet Jan 07 '11 at 16:23
  • Oh, great expert of SO, please give us a rundown of the extent of the dangers of SQL Injection with a Jet/ACE data store. You might want to search SO before replying with that... – David-W-Fenton Jan 08 '11 at 03:31
  • @David-W-Fenton: It seems to me that *some* classes of SQL injection attack aren't applicable here (those involving DML), but other classes could be (those with straight `"WHERE X='"+input+'"` code. (I've read your post at http://www.pcreview.co.uk/forums/thread-4021211.php which mentioned this, and the related SO posts). In addition, parameterized SQL keeps data separate from code, which I view to be general cleaner. Finally, I can *easily* see someone porting this code from Jet/ACE to another database platform without reconsidering every possible danger. – Jon Skeet Jan 08 '11 at 08:24
  • Also forgot to mention that it means you don't need to worry about "cleaning" or escaping the input. I view parameterized queries as the *best* way to cope with, say, a surname of O'Reilly. I dare say there are Jet/ACE-specific routines to perform escaping - but what are the benefits of those over using a technique which will be broadly portable across databases? (You may need to change between named and additional parameters, but the basic approach will be the same.) – Jon Skeet Jan 08 '11 at 08:28
  • I think your perspective is one that is wrong. You seem to be coming to it from a web-based perspective, and I don't consider Jet/ACE to be an appropriate database for any web-based application. Of course, you can use Jet/ACE from the .NET languages or Delphi or whatever development environment. In that case using a db abstraction layer is probably a good thing and that will make parameterization pretty much the only way to do things. In an Access environment, none of these things are all that relevant (and that's the context in which I wrote my long post on Access SQL Injection). – David-W-Fenton Jan 09 '11 at 23:53
  • @David-W-Fenton: I don't see what this has to do with being on the web or not. Would user data never include a name like "O'Reilly" except on the web? Why would an abstraction layer not be good *software engineering* practice in an environment using Jet/ACE? Why would using standard good practice which is immediately portable to a different database later on (both in terms of developer skills and actual code) not be a good idea when using Jet/ACE? What's the *disadvantage* of using standard best practices? I suspect we may have to agree to disagree... – Jon Skeet Jan 10 '11 at 06:25
  • @David-W-Fenton: Bear in mind that we can already tell that the OP *is* using Jet/ACE from a .NET language (C#). Note that your comment on the question itself (about the date separator for Access) is an example of exactly the kind of thing one *shouldn't* have to worry about - and which parameterized queries can isolate from you. Why should I care about the *text* format of dates? I just want the *data*! – Jon Skeet Jan 10 '11 at 06:28
  • Again, I think you're missing my point. I'm referring to the SO explanation of SQL Injection issues in Access applications, and in that regard, all your points are off-base. You likely wouldn't build an Access QBF interface that just allowed the user to type in free text (if you did, you're making it harder for your users, in most cases). In regard to the other environments, I'm all for an abstraction layer. In Access itself, it's inadvisable to use anything other than Jet/ACE as your intermediary to other data sources, so for the most part, your code will be db engine agnostic to begin with. – David-W-Fenton Jan 11 '11 at 22:20
  • I would expect a proper generalized database interface of any kind to take care of issues like delimiters and wildcards, and when I use SQL Server from Access using ODBC, I don't have to worry about the target DB's specifics in this regard. I don't know if the interface the original poster was using handles this for him or not. If it doesn't, it's not a terribly helpful interface, in my opinion. In only offered the suggestion as a way of working around that interface's inadequacies (assuming that's the reason it's not working). – David-W-Fenton Jan 11 '11 at 22:23
  • @JonSkeet I ask a related Question here: http://stackoverflow.com/questions/14475968/read-access-file-accdb-from-stream , would you please check it – Saeid Jan 23 '13 at 09:44
  • 1
    @Saeid: That doesn't actually seem related at all. – Jon Skeet Jan 23 '13 at 09:51
  • @JonSkeet Your right, but actually I search any where to find any solution, Then find you here, thanks for attention – Saeid Jan 23 '13 at 09:53
  • @Saeid: So you think it's appropriate to just add a comment on an answer to an unrelated question? Sorry, but it's not. – Jon Skeet Jan 23 '13 at 09:54
4

I posted this as a comment to the duplicate question at: Syntax error in INSERT INTO statement in c# OleDb Exception cant spot the error

Put brackets [] around the table name "User". It's a reserved word in SQL Server.

"User" is also a reserved word in Access (judging by the provider in your connection string).

But I completely agree with Jon--if you fix your current implementation, you are just opening up a big security hole (against your User table, no less!)

Community
  • 1
  • 1
Tim M.
  • 53,671
  • 14
  • 120
  • 163
1

This problem may occur if your database table contains column names that use Microsoft Jet 4.0 reserved words.

Change the column names in your database table so that you do not use Jet 4.0 reserved words.

user3183270
  • 135
  • 1
  • 8
0

After this

cmd.CommandText="INSERT INTO User ([UserID], [Forename], [Surname], [DateOfBirth], [TargetWeight], [TargetCalories], [Height]) Values ('" + userid.Text.ToString() + "' , '" + fname.Text.ToString() + "' , '" + sname.Text.ToString() + "' , '" + dob.Text.ToString() + "' , '" + tarweight.Text.ToString() + "' , '" + tarcal.Text.ToString() + "' , '" + height.Text.ToString() + "')";

check what this contains, maybe [DateOfBirth] has illegal format

CLARK
  • 88
  • 7
0

If TargetWeight, Height, and TargetCalories are floating-point or integer values, they don't need to be surrounded by quotes in the SQL statement.

Also, not directly related to your question, but you should really consider using a parameterized query. Your code is very vulnerable to SQL injection.

Brennan Vincent
  • 10,736
  • 9
  • 32
  • 54
0
public decimal codes(string subs)
    {
        decimal a = 0;


        con_4code();
            query = "select SUBJINTN.[SCODE] from SUBJINTN where SUBJINTN.[ABBR] = '" +                         subs.ToString() + "'";
            cmd1 = new OleDbCommand(query, concode);
            OleDbDataReader dr = cmd1.ExecuteReader();

here is error in dr it says syntax error ehile in DBMS its working Well

            if (dr.Read())
            {
                a = dr.GetDecimal(0);
                MessageBox.Show(a.ToString());
            }
            return a;



    }
  • 1
    OleDbDataReader dr = cmd1.ExecuteReader(); on this point its showing its a syntax error while the simple quary working good......... – user1289578 Mar 26 '12 at 08:36