views:

216

answers:

4

Hello everyone

I have searched, but nothing happens, I just starting using C#.NET and I a have a textbox on a form. I retrieve some data from the database and I display to a textbox through a combobox that indicate the section I want to display (I already do this!),but when I try to update nothing works, I click my button to update the access database(Access 2007) and nothing happens, the user just changes something and the button has to update the acces database, I hope you can help me :D this is my code so far:

        String textTobeUpdated = textBox3.Text;
        String thing = comboBox2.Text;




        using (var conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=MyDataBase.accdb"))

        using (var cmd = conn.CreateCommand())
        {


            cmd.CommandText = "UPDATE Section SET content = [@content] WHERE name= thing";
            cmd.Parameters.AddWithValue("@content",content);


            conn.Open();



            int rowsAffected = cmd.ExecuteNonQuery();
            if (rowsAffected == 1)
            {
                MessageBox.Show("Success");
            }
            else
            {
                MessageBox.Show(string.Format("{0} Rows Affected", rowsAffected));
            }

this code display a message that tells "Unhandled exception. If click in continue, the application will omit this error and intent continue. If click in exit, the application will close immediately" The are no especified value for some of the required parameters.

A: 

Looks like you execute the query twice (two areas where you call cmd.ExecuteNonQuery(); )

Remove the first one and leave the line that says

int rowsAffected = cmd.ExecuteNonQuery(); 

This line will perform the update, then count how many rows were updated. This count is then used to display a message to the user.

You're also not setting the content variable with a value, (I guess it should be the textbox value), and the update query itself seems a little odd, you haven't parameterised the 'thing' you're updating, so I guess it should be:

cmd.CommandText = "UPDATE Section SET content=[@content] WHERE name=[@thing]"; 
cmd.Parameters.AddWithValue("@content", textTobeUpdated);
cmd.Parameters.AddWithValue("@thing", thing);
Slartibartfast
It just display a message that tell me unhandled exception by the application
Natalie
@Natalie. If you update your original question with the exception text it might help.
Slartibartfast
I edited, it seems that something is wrong in the query I suppose
Natalie
I still have problems, because its no updating the database, its just updating the textbox
Natalie
A: 

If you are new to .NET and using a recent version of C#, then I would recommend that you write your data access code using LINQ.

You have to learn LINQ, but that is much more natural than learning ADO.NET.

You would then use a Repository classes to write the data access for your app, and you end up with a much more maintainable code base.

I think Slartibartfast's solution is correct, given the code, but I post this as an answer not a comment because using LINQ is the easier learning curve. You can then learn ADO.NET if you need to.

EDIT:

I think the bits of C# you need to read up on are LINQ, LINQ to SQL, LINQ to Entities, as well as the Repository Pattern for encapsulating Data Access code. Your code above is written using ADO.NET, which is the hard, low level way of doing it. Unless you have reams of legacy code, then LINQ is the way to go, I feel.

a. LINQ:

LINQ stands for language integrated query and it allows you to query a collection of objects much like you would a database. But it is also, in its LINQ to SQL and LINQ to Entities flavours, a Data Access technology. It allows you to query, create, edit and delete data in a database (or other datastore). It "looks" like SQL, but is strong typed.

b. Repository Pattern:

The Repository Pattern is a pattern that allows you to standardise (and test if so inclined) your data access code, all encapsulated in a class. It makes your code MUCH more maintainable.

The internet is awash with discussions, blogs and samples of how to use LINQ.

EDIT TO PROVIDE SAMPLE LINQ TO SQL OPTION:

The bare bones of what you want to do would be, roughly:

Assuming you have created the DBML file called dbDataContext, and that the record you want to update is in a table called MyTable:

// instantiate the datacontext object using the connection string
var db = new dbDataContext("myConnectionString");

// retrieve the record to update
var record = (from r in db.Section where r.Name == "thing" select r).Single();

if (record != null) record.Content = "Content";

try
{
// try to update the database
db.SubmitChanges();
MessageBox.Show("Success!");
}
catch
{
// Darn!  Didn't work...
MessageBox.Show("Ooops!");
}

Note how readable this is.

awrigley
thanks for suggestion, I think that I need to understand better all the concepts, I knoW a little bit Java
Natalie
I think that is more readable, I need to learn Linq, and use in a project thanks for answering
Natalie
Where can I find information about using LINQ To SQL with an Access ACCDB or MDB database file?
HansUp
http://stackoverflow.com/questions/295772/query-microsoft-access-mdb-database-using-linq-and-c
awrigley
The above linq states that instead of using LINQ to SQL, you use the Entity Framework to create the equivalent of the .dbml file (ie, your data context) and then use LINQ with that.
awrigley
The above linq states that instead of using LINQ to SQL, you use the Entity Framework to create the equivalent of the .dbml file (ie, your data context) and then use LINQ with that.
awrigley
When using LINQ to ENTITIES (as opposed to LINQ to SQL that only works with sql server dbs, my apologies), the sample code above is virtually identical. You need to buy a book on LINQ and get to grips with what it is and how it works. If you are writing a lot of data access code, it is worth it.
awrigley
"The above linq states ..." That was funny! A chain is only as strong as its weakest LINQ. :-)
HansUp
A: 

I doubt Access' database engine (ACE) will accept your UPDATE statement.

Here is an UPDATE statement which will work in Access, and change the content field values to "my updated contents" for all rows where a text field, name, is equal to "thing".

UPDATE [Section] SET content = 'my updated content' WHERE [name] = 'thing'

Compare that WHERE clause to your original:

WHERE name= thing

Without quotes to identify thing as a string value, ACE will not know what thing represents. The lack of quotes is probably the cause of your error message: "The are no especified value for some of the required parameters." ACE doesn't know what thing is, so treats it as a (missing) parameter.

Also notice I enclosed Section and name in square brackets. Both are reserved words; the brackets signal ACE they are table and field names respectively. See Problem names and reserved words in Access

HansUp
See it my table is called Section, it has a field content, so I called too "content" the textbox, also has a field name that is linked to the text of a combobox(example Introduction), I called the combobox thing, whenever I pick a section of the combobox the texbox display that content.
Natalie
Again, as LINQ is strongly typed, these naming issues with reserved words disappear.
awrigley
I don't know LINQ. Are you saying it can operate directly on the ACCDB file without involving ACE?
HansUp
No. What LINQ to SQL does is create classes in the .NET project where the code is called from. These classes allow LINQ to make strongly typed calls. LINQ then uses these calls to auto generate the SQL that will be used. This auto generated SQL string will automatically have fields and table names wrapped in square brackets (eg, [Section]), so there is never a conflict when LINQ is used.
awrigley
Take a look at the second Edit of my answer. For example the line:
awrigley
var record = (from r in db.Section where r.Name == "thing" select r).Single();
awrigley
In that line, r.Name is a strongly typed call to the Name property on the object r. As this is a .NET object instead of an Access table column, there is no conflict with ACE or JET because LINQ will create safe sql strings under the covers. Ie, LINQ is worth investing time in learning it.
awrigley
LINQ is communicating with Jet/ACE, so reserved words still matter, because they are reserved words in *Jet/ACE*. Whether or not LINQ is smart enough to fix up the SQL to avoid any reserved words in Jet/ACE I couldn't say. I wouldn't depend on it, myself, and put the brackets in the SQL that I'm passing to LINQ.
David-W-Fenton
Thanks for the explanation, @awrigley. That was interesting. It didn't occur to me that strongly-typed meant LINQ would wrap all db object names in brackets.
HansUp
However wonderful LINQ might be in fixing up your mistakes in using reserved words, I wouldn't depend on it having an accurate list of Jet/ACE's reserved words, and I'd write my SQL with the brackets anyway.
David-W-Fenton
@David When/if I use LINQ with Jet/ACE databases, I suspect I'll do the same as you. However, that shouldn't be a frequent requirement because I scrupulously avoid reserved words as database object names. It could only be an issue if I inherit a db created by someone else.
HansUp
A: 

Change: cmd.CommandText = "UPDATE Section SET content = [@content] WHERE name= thing";

To: cmd.CommandText = "UPDATE Section SET content = ? WHERE name= thing";

Through OleDB I don't think you can name the parameter in the command text to Jet/ACE. If you have more than one parameter, you'll have to keep them in order and continue to use '?'.

...Where [This] = ? AND [That] = ?;

Add parameters in the correct order.

Jeff O
thanks for asnwering but I add the parameters in correct order but nothing happens when I check the access database, theres no change
Natalie
Did you use a question mark instead of the name of the parameter in the commandtext?
Jeff O