MS Access DB doesnt save changes after execution (C#) - c#

I have the following code for using an access database
OleDbConnection con = new OleDbConnection(myproject.Properties.Settings.Default.myDBConnectionString);
con.Open();
OleDbCommand command = new OleDbCommand("INSERT INTO components (name) VALUES (#p_col1)", con);
command.Parameters.Add("#p_col1", OleDbType.VarChar).Value = "test row";
int rows = command.ExecuteNonQuery();
At this point rows value is 1 and when I make select queries after that the row inserted is available. The problem comes when the program finishes: in further executions that row isn´t there anymore.
I´ve tried with transactions
OleDbTransaction transaction = con.BeginTransaction();
command.Transaction = transaction;
transaction.Commit();
and using DataSets and ADO this way
//... add row to dataset ...
OleDbDataAdapter sda = new OleDbDataAdapter("select * from components", con);
OleDbCommandBuilder cb = new OleDbCommandBuilder(sda);
sda.Update(ds.Components); //tried with ds.Components.AcceptChanges(); before and after this line
but in every case i have the same problem, seems like the insert query is not done in the real database. Do you know why can this be happening???
Thanks in advance

Is the database in your bin directory? Is it also part of your project? I have seen this happen when every time you build it overwrites the database in your bin directory with the one from the project directory, so it appears things are not getting saved.

There may be more than one database and you are not inserting to the one you think you are inserting to.

MS Visual Studio builds the Access DB into the product.
--- The product is located in your bin directory.
--- To view any and all changes to your DB via application use this one
When you initially add the DB to the project, it is set to always update the product on build.
This can be a good thing, but I find it rather annoying.
In order to fix this:
Select the MS Access DB from your Solution Explorer,
Hit F4 to go to it's properties,
Change the field "Copy to Output Directory" to "Copy if newer" instead of "Always".

Related

There is no record in the Table - SQL C#

I'm having a problem with SQL. I'm new to C# so I don't really know what to do.
Here's the code:
public static void addMemo()
{
schedule sch = (schedule)Application.OpenForms["schedule"];
using (SqlConnection conn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\_data\schedData.mdf;Integrated Security=True"))
{
SqlCommand CmdSql = new SqlCommand("INSERT INTO schTable (evnName, evnDate, evnTime, evnStatus) VALUES (#evnName, #evnDate, #evnTime, #evnStatus)", conn);
conn.Open();
CmdSql.Parameters.AddWithValue("#evnName", sch.txtName.Text);
CmdSql.Parameters.AddWithValue("#evnDate", sch.txtDate.Text);
CmdSql.Parameters.AddWithValue("#evnTime", sch.txtTime.Text);
CmdSql.Parameters.AddWithValue("#evnStatus", "Upcoming");
CmdSql.ExecuteNonQuery();
sch.lblNotifier.Text = sch.txtName.Text + " Added.";
conn.Close();
}
}
Everything works fine, there are no errors. But when I looked into the table, there was nothing. I cannot see my inputs. Can someone help me?
EDIT - Here I have a working code that I made before in VB.Net I'm trying to use this instead but I'm stuck with the Tables part. (I'm a noob at c#)
Private ConStr As New String("Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\data_\database.mdf;Integrated Security=True")
Dim MyNewRow As DataRow = SqlDatTbl.NewRow()
SqlDatTbl.Rows.Add(MyNewRow)
SqlRowPos = SqlDatTbl.Rows.Count - 1
SqlCon.ConnectionString = ConStr
SqlCon.Open()
SqlDatAdp = New SqlDataAdapter("Select * from Events", SqlCon)
SqlCmbBld = New SqlCommandBuilder(SqlDatAdp)
SqlDatAdp.Fill(SqlDatTbl)
If SqlDatTbl.Rows.Count <> 0 Then
SqlDatTbl.Rows(SqlRowPos)("Name") = txtName.Text
SqlDatTbl.Rows(SqlRowPos)("Date") = txtDate.Text
SqlDatTbl.Rows(SqlRowPos)("Time") = txtTime.Text
SqlDatTbl.Rows(SqlRowPos)("Status") = "Upcoming"
SqlDatAdp.Update(SqlDatTbl)
MsgBox("New Event Added")
End If
SqlCon.Close()
When working with an attached database and that database is being shown in Solution Explorer there is a property, "Copy to output directory" where the default setting is "Copy Always". So if you were to assign a variable to ExecuteNonQuery and the results show a value higher than 0 then you will need to set "Copy to Output Directory" to "Do not Copy" and then manually copy the database into the Bin\Debug or Bin\Release folder or set "Copy to Output Directory" to "Copy if Newer" which means unlike "Copy always" this value will only copy the database to the app folder if you make any changes to the database in the project folder. I have a article with samples and explanations for you to try out MSDN Working with Copy to Output Directory.
Here is the default setting
If ExecuteNonQuery returns 0 then the above is not the issue.
Have you checked to make sure that sch.txtName.Text and sch.txtDate.Text and sch.txtTime.Text actually have values in them? Insert a breakpoint on conn.Open(); and then if you mouse over sch.txtName.Text, sch.txtDate.Text, and sch.txtTime.Text in your code, then it should show a little tooltip with information about the field you are mousing over. Here's an image showing what it looks like for me with a chunk of some random code. The popup has an arrow on the left side that opens up if you mouse over it. That'll give you more information about the variable you are looking at. If your text values are empty, then it has nothing to write to the database. Depending on how the database is configured, that could mean that it doesn't write anything at all or that it writes empty fields.
Since you said you are new, if you don't know how to add a breakpoint, you can add one in visual studio by right clicking on the line you want to put the breakpoint at and then under the breakpoints sub-menu, click on Insert breakpoint. Now when you run your code in debug mode and it gets to that point, it will stop and let you see what's going on.

How to save DataSet after adding data?

Yes, I know that this questions has been asked at least 5-10 times in here, but I can't for the life of me get any of the methods to save the data.
The idea is to create a new row in table Companies in column Name (there is only one column) with value "asdf"`.
I've tried combinations of the following:
DatabaseDataSetTableAdapters.CompaniesTableAdapter adapter = new DatabaseDataSetTableAdapters.CompaniesTableAdapter();
DatabaseDataSet ds = new DatabaseDataSet();
adapter.Insert("asdf");
adapter.Fill(ds.Companies);
adapter.Update(ds.Companies);
ds.AcceptChanges();
ds.Companies.AddCompaniesRow("asdf");
ds.Companies.AcceptChanges();
ds.Companies.AddCompaniesRow("asdf");
ds.Companies.Rows[0]["Name"] = "asdf";
adapter.Update(ds.Companies);
I'm using C# WPF .NET 4.5.1
It does add the data, but it doesn't save it when I exit the program - I know that it adds data, because if I call this method twice it crashes, because the value is no longer unique.
Here is the DatabaseDataSetTableAdapters:
http://pastebin.com/gNsaRFD5
This did not work either:
SqlConnection myConnection = new SqlConnection(global::AliBabaMailer.Properties.Settings.Default.DatabaseConnectionString);
myConnection.Open();
SqlCommand myCommand = new SqlCommand("INSERT INTO Companies (Name) " +
"Values ('string')", myConnection);
myCommand.ExecuteNonQuery();
myConnection.Close();
Ok so your problem is the Connection String:
Properties.Settings.Default.DatabaseConnectionString
This connection string is of the form:
“Data Source=ServerName;AttachDbFilename=|DataDirectory|\DataBaseName;Integrated Security=True”
The |DataDirectory| is usually here:
C:\Users\UserName\AppData
When you save the data it is being saved to a database file at `|DataDirectory| location but when you try to view the data using Server Explorer you are trying to view from a database file which is in your project's folder, that is why If you try to save and then view the data on run time it will work fine because then you will be querying the same database you are storing your data into.
|DataDirectory|:
|DataDirectory| (enclosed in pipe symbols) is a substitution string that indicates the path to the database. It eliminates the need to hard-code the full path which leads to several problems as the full path to the database could be serialized in different places. |DataDirectory| also makes it easy to share a project and also to deploy an application.
For example, instead of having the following connection string:
"Data Source= c:\program files\MyApp\Mydb.sdf"
Using DataDirectory, you can have the following connection string:
“Data Source = |DataDirectory|\Mydb.sdf”
To set the DataDirectory property, call the AppDomain.SetData method. If you do not set the DataDirectory property, the following default rules will be applied to access the database folder:
For applications that are put in a folder on the user's computer, the database folder uses the application folder.
For applications that are running under ClickOnce, the database folder uses the specific data folder that is created.
Link
Coding Advice:
Try to dispose your Command and Connection Objects like this:
using(SqlConnection myConnection = new SqlConnection(global::AliBabaMailer.Properties.Settings.Default.DatabaseConnectionString))
using(SqlCommand myCommand = new SqlCommand("INSERT INTO Companies (Name) " + "Values ('string')", myConnection))
{
myConnection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}

OleDbCommand.ExecuteNonQuery() does not save changes in ms access database

I have .mdb database, and code like this:
using (OleDbConnection connection = new OleDbConnection(myConnectionString))
{
using (OleDbCommand cmd = connection.CreateCommand())
{
cmd.CommandText = "UPDATE myTab SET col2 = #val1 WHERE col1 = #val2";
cmd.Parameters.AddWithValue("#val1", 0);
cmd.Parameters.AddWithValue("#val2", -1);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
}
}
I get data from db, change it in my gui programm, then save it in db. Changes saves, but not in db (I don't know where), so when I run program, change data, close program, then again run - changes remain, but when I open db (not in programm), there are no changes saved, and again run - all changes disappear.
PS: when I commit changes, then run program several times, all changes disappear too, after (3-4 runs)
When we we add .mdb in project root in VS ,when change structure ,VS default delete .mdb file in debug folder and replace new file; now you can change this defult :
1- right click .mdb file and select option
2- set Copy To Output Directory to Do Not Copy
It is most likely the WHERE clause of your update statement isn't locating any records to update.
http://weblogs.asp.net/stevewellens/archive/2009/10/16/why-sql-updates-fail-three-reasons.aspx

SQL Server Express inserts doesn't work anymore

In my C# application, I do the following:
using (SqlConnection connection = new SqlConnection(connectionstr))
{
connection.Open();
SqlCommand com1 = new SqlCommand("insert into Anfangstierbestand(bestand, jahr, loginid) VALUES (" + bestand + ", " + jahr + ", " + loginid + ");", connection);
SqlCommand com2 = new SqlCommand("select * from Anfangstierbestand;", connection);
com1.Connection = connection;
int ferksum = 0;
com1.ExecuteNonQuery();
connection.Close();
connection.Open();
SqlDataReader read = com2.ExecuteReader();
while (read.Read())
{
ferksum += Convert.ToInt32(read[2]);
}
// MessageBox.Show("Fehler beim Erstellen des Tierbestandes", "Fehler"); }
MessageBox.Show(ferksum.ToString());
}
It's a simple insert to a database. I added com2 to check, if the insert works.
Unfortunately, the the value of com2 tells me, that it works, but when I go to the Server Explorer and press Execute SQL, there are no new values.
I don´t know the reason. The code above is just an example, since a few days, no insert works anymore(before, the same code works).
Does anybody know what the reason can be?
EDIT:
C#:
string connectionstr = "Data Source=.\\SQLEXPRESS;" + "AttachDbFilename=|DataDirectory|\\Datenbank\\FarmersCalc.mdf;" + "Integrated Security=True;" + "User Instance=true;";
EDIT2:
Server Explorer:
Data Source=.\SQLEXPRESS;AttachDbFilename="C:\Users\user\Desktop\Farmer´s Calc\Programmierung\WPF\Finanz_WPF\Finanz_WPF\Datenbank\FarmersCalc.mdf";Integrated Security=True;User Instance=True
EDIT3:
Here are the columns:
id int,
jahr int,
anzahl int,
loginid int
EDIT4:
Is it possible that it´s a problem that I opened my project with expression blend? Normally, I work with VS 2010...
EDIT5:
Even because I can not answer my question(<100 reputations) I write it here:
Shame on me. Some of you were right, it was the wrong database-file. But I´m still wondering, why this happened, because I did not change anything since a few days and before this, it worked!
Thanks to all for helping!
You're using user instances, why? Isn't it possible that the instance you're connecting to in Server Explorer is not the same as the instance where your app is inserting data? What happens when you select data from within the app, does it reflect your insert(s)? It seems to me based on your connection strings that these are two completely different MDF files - they have the same name but they are in different locations.
Is the issue implicit transactions? Do you need to issue a commit of the SQL Insert? If com2 tells you that it's there then it may only see it since it's in the context of the current SQL transaction.
You should share your connection string for both Server Explorer and your SqlConnection (connectionstr). Ensure that you setup your Server Explorer connection with User Instance=true;.
As a diagnostic,
connection.Open();
int n = com1.ExecuteNonQuery();
// log or show 'n' , the nr of rows affected
Edit, after seeing the connectionstrings:
local db files in |DataDirectory|\ are very prone to be overwritten by the next run or build command.
Make sure you set them to 'copy never' or 'copy if newer' in the VS Solution explorer.
Perhaps somewhere in the callstack above this code, someone has added a TransactionScope.
This would cause the connections to enroll automatically in the transaction, and the connections could see the data inserted via that not-yet-committed transaction. When the scope is exitted without calling scope.Complete, the transaction gets rolled back and no data is saved.

Update database using SqlCeDataAdaptor

I populate a listview from a Dataset that accesses sqlserver in visual studio 2008 express edition. I've been trying to update the listview and database simultaneously.
SettingTxt.Text references a textbox
With the following code, I've been able to update the list view with the information entered into the textbox, but the same update is not performed in the database. If anyone can help me resolve this, I would greatly appreciate it. I know there are alot of forums online regarding this exact problem, but I can't seem to get it working.
thisConnection = new SqlCeConnection("Data Source=AugMedDB.sdf;Password=");
thisConnection.Open();
SqlCeCommand cmd = thisConnection.CreateCommand();
cmd.CommandText = "UPDATE Patient SET Setting = \'" + SettingTxt.Text + "\' WHERE (PtID=0) AND (EquipID=1) AND (Control='Lever')" ;
SqlCeDataAdapter adp = new SqlCeDataAdapter();
adp.UpdateCommand = cmd;
dataSet.Tables[0].Rows[0][2] = SettingTxt.Text;
adp.Update(dataSet);
Thanks in advance.
Moved from an answer:
What I currently have is:
SqlCeCommand cmd = thisConnection.CreateCommand();
cmd.CommandText = "SELECT column FROM table WHERE id=0";
SqlCeDataAdapter adp = new SqlCeDataAdapter(cmd);
adp.SelectCommand = cmd;
DataSet ds = new DataSet();
ds = dataS.getDataSet();
adp.Fill(ds, "Patient");
SqlCeCommand comm = thisConnection.CreateCommand();
comm.CommandText = "UPDATE table SET Setting = 'value' WHERE (PtID=0)";
adp.UpdateCommand = comm;
adp.Update(ds, "Patient");
And I'm not understanding all the tutorials I find. Thanks in advance.
Update:
Yet even something as simple as the following doesn't update the database:
SqlCeConnection thisConn = new SqlCeConnection("Data Source=AugMedDB.sdf;Password=");
String query = "UPDATE Patient SET Setting = 'TopyTruck' WHERE (PtID=0) AND (EquipID=1) AND (Control='Lever')";
thisConn.Open();
SqlCeCommand commd = new SqlCeCommand(query, thisConn);
commd.ExecuteNonQuery();
thisConn.Close();
Your UPDATE statement is not suitable for an Adapter.Update(), for that it needs parameters and must be aligned with the SELECT statement.
You could try to execute that Command directly (w/o the adapter) or create a better update statement (using the dataset designer ).
Update
After filling the dataset,
generate the other SQL statements with a CommandBuilder (I think it exists for SqlCe)
or use your use your own Update command without the adapter. Just call comm.ExecuteNonQuery()
Tip 1: It may help to create a temporary (WinForms) project and use the VS tools to "Add a Datasource". You can look in the Dataset designer how VS generates the commands etc.
Tip 2: There are other options available, like entity framework. Datasets are (becoming) an "end of life" tech.
Thank you so much for all your help. I actually found the source of the problem. I had multiple references to the database; one within my project and another copy in bin/debug. I was correctly updating the copy in bin/debug but I was looking at the copy in my project. Once I deleted all copies, other than the one in bin/debug, it all worked and made sense. Now I see the updates in the database in bin/debug/

Categories

Resources