views:

367

answers:

2

I am attempting to run a parameterized query against a DB2 database from .NET using the Client Access ODBC Driver using the following code:

var db2Cmd = new OdbcCommand("INSERT INTO presnlats (LAT) VALUES (@LAT)", db2Conn);
db2Cmd.Parameters.AddWithValue("@LAT", insertValue);
Console.Out.WriteLine(db2Cmd.ExecuteNonQuery());

When executed, an OdbcException is thrown:

ERROR [42S22] [IBM][iSeries Access ODBC Driver][DB2 UDB]SQL0206 - Column @LAT not in specified tables.

The internets seem to imply that parameterized queries are supported by the client access ODBC driver, but this error seems to indicate otherwise. Is there anything wrong with the supplied code?

+2  A: 

Have you tried using ? as the placeholder instead of @LAT?

var db2Cmd = new OdbcCommand("INSERT INTO presnlats (LAT) VALUES (?)", db2Conn);

db2Cmd.Parameters.AddWithValue("LAT", insertValue);

Console.Out.WriteLine(db2Cmd.ExecuteNonQuery());

This is what MS Access requires when using OdbcConnection / OdbcCommand.

You just need to make sure your Parameters.AddWithValue() statements are in the same order as the field list in the INSERT statement. First parameter passed to AddWithValue() doesn't seem to matter, although by convention I make it the same as the field name.

tomfanning
Take it this worked? Sometimes the simple solutions work out best hey :-)
tomfanning
A: 

If I'm guessing right at what you're trying to do you want to do this:

You want to add ONE parameter, and need to change the VALUE of the parameter in the loop.

var db2Cmd = new OdbcCommand("INSERT INTO presnlats (LAT) VALUES (@Lat)", db2Conn);
db2Cmd.Parameters.AddWithValue("@Lat", 0);


for (int j = 0; j < reader.FieldCount; ++j)
{
   db2Cmd.Parameters["@Lat"].Value = reader[j];
   Console.Out.WriteLine(db2Cmd.ExecuteNonQuery());
}

Added

You only have one placeholder (@Lat) for your parameter in the command, so you should be adding only one parameter. Your code is adding a new parameter for every object in the reader. Not one of those parameters would be named "@Lat" unless youre reader is returning a value of @Lat.

I'm still pretty positive that you need one parameter (@Lat) and need to modify the value of the parameter in the loop.

Clarifying the syntax of using parameteized queries, consider this statement:

cmd.CommandText = "Insert Into Person (FirstName, LastName) Values (@fName, @lName)

In the above statement, @fName and @lName are NOT parameters. They are placeholders for parameters.

You need to then explicitly add the paramaters using the following rules:

  • The parameters must be named exactly the same as the placeholders
  • The parmaters must be added in the right order.

So a more full example would be

cmd.CommandText = "Insert Into Person (FirstName, LastName) Values (@fName, @lName)

cmd.Parameters.AddWithValue("@fName", "David"); // This line, in this context, says "Repalce the parameter palceholder from the previous line with this actual parameter. cmd.Parameters.AddWithValue("@lName", "Stratton"); // similarly, this replaces the @lname placeholder.

Then if I have a datareader that has a bunch of names, I can repleatedly assign the VALUE fromthe reader to the VALUE of the parameter.

while (myReader.Read()) { cmd.Parameters["@fName'].Value = myReader.GetString("FirstNameField"); cmd.Parameters["@lName'].Value = myReader.GetString("LastNameField"); cmd.ExecuteNonQuery();

}

David Stratton
The command and its parameters are correct, but the example hides some code and doesn't make this clear. I'll clarify it.
Mike
OK. The new code invalidates even my added text.
David Stratton