I am trying to update a record in an access file (.accdb). I am trying to use the .net OleDbCommand and OleDbParameters. I am also trying to use a generic model and store all of the commands and parameters in the System.Data.Common abstract equivalents so that I can easily switch over to SQL Server (which I do plan to do)
So here is the actual command being used
EDIT 2/2/2013 – 9:10pm
the command.ExecuteNonQuery is inside the method named ExecuteNonQuery()
the connectionString and command are defined in the DataAccess class constructor
public class DataAccess
{
private string connectionString;
private DbConnection connection;
private DbCommand command;
private DbDataReader reader;
private DataTable data;
public DataAccess()
{
connectionString = ConfigurationSettings.AppSettings["ConnectionString"];
switch (ConfigurationSettings.AppSettings["DataBaseType"])
{
case "oledb":
connection = new OleDbConnection(connectionString);
command = new OleDbCommand(string.Empty, (OleDbConnection)connection);
break;
case "SQL":
connection = new SqlConnection(connectionString);
command = new SqlCommand(string.Empty, (SqlConnection)connection);
break;
default:
break;
}
}
public void ExecuteNonQuery(string SQL, params DbParameter[] parameters)
{
command.CommandType = CommandType.Text;
command.CommandText = SQL;
command.Parameters.AddRange(parameters);
try
{
command.Connection.Open();
try
{
command.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
command.Connection.Close();
}
}
catch (Exception ex)
{
throw ex;
}
}
public DbParameter NewParameter(string name, object value)
{
DbParameter param;
switch (ConfigurationSettings.AppSettings["DataBaseType"])
{
case "oledb":
param = new OleDbParameter(name, value);
break;
case "SQL":
param = new SqlParameter(name, value);
break;
default:
param = null;
break;
}
return param;
}
These are the properties in the App.Config File
<add key="DataBaseType" value="oledb"/>
<add key="ConnectionString" value="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=data.accdb"/>
Now the problem is when using parameters in an update statement, the update never happens and also never throws an error. Here is the code for it.
EDIT 2/2/2013 – 9:10pm
the function DataAccess.NewParameter is in the first code block
DALayer.ExecuteNonQuery("UPDATE TileTypes SET Title = @Title, Picture = @Picture, Color = @Color WHERE ID = @ID",
DALayer.NewParameter("@Title", titleTextBox.Text.Trim()),
DALayer.NewParameter("@Picture", typePictureBox.ImageLocation),
DALayer.NewParameter("@Color", colorButton.BackColor.ToArgb()),
DALayer.NewParameter("@ID", id));
I have copied the query into access and replaced all of the parameter names with the actual data being passed, this works fine. I have tried replacing all of the parameters in the SQL text to the ? character to no effect. I have tried enclosing all of the table and column names in brackets [] also to no effect.
- ID is an AutoNumber field
- Title is a Text field
- Picture is a Text field
- Color is a Long Integer field
This is some example data that was copied directly from the parameters in the watch window for Visual Studio:
- “Edit” (title)
- -1 (color)
- “data\images\Edit_000000.jpg” (picture)
- 740 (id)
That ID does exist in the database and was unchanged after the query executed.
EDIT 2/2/2013 – 9:10pm
I am not sure how to check which database is actually being updated, the only thing I could think of was that using the same connection string and connection object I did an insert statement with the same ExecuteNonquery method and it worked in the database I was viewing. And the update statement works just fine like this (without parameters):
DALayer.ExecuteNonQuery("UPDATE TileTypes SET Title = '" + titleTextBox.Text +
"', Color = " + colorButton.BackColor.ToArgb() + ", Picture = '" +
imageLocation + "' WHERE ID = " + id);
EDIT 2/2/2013 – 9:41pm
I have used everything.exe to search my computer for all of the data.accdb files on my computer, I have found no actual .accdb files besides the original but I did find these .lnk files, I do not believe they could have altered this process but I will mention it anyway
data.accdb.LNK
What you are trying to do is something I too have done in the past, but allowed to connect to OleDB (such as Access, Visual FoxPro, etc), SQL-Server, SyBase SQLAnywhere and maybe my implementation might help you. First, each of the elements you would use for connecting work on a common interface, such as IDbConnection, IDbCommand, IDbParameter, etc.
The following I’m posting is a small segment of how I originally structured such multi-database connection type. I’ve stripped a bunch out and not actually tested this stripped version, but it SHOULD be a good baseline for you to run with.
The premise is a baseline “MyConnection” to almost be like an abstract, but has properties and some “common” methods that would exist under EITHER subclassed definition. From this, each of the functions and parameter types are based on the “I”nterface, not a specific. However, each of the derived will create its OWN proper type. This removes the need to “Case” everything. Hope this helps you along with your Data Access Layer development.
So.. as you can see, my last class specifically is derived from EITHER Access OR SQL. Then, I can create my methods to get data, call updates, whatever. Get a SQL Command (which returns proper type and automatically is attached to its corresponding “Connection Handle” object, prepare the text, add your parameters, execute it.