local database won't update and doesn't show errors - c#

Hey i'm new to this and from what i managed to pick up this should be working but it doesn't update my local database.
I have a TelemarketingDatabaseDataSet that was auto generated when i created my local database, which then i dragged the table onto the dataset and i guess they're linked.
Now i have this code :
SqlCeConnection connection = new SqlCeConnection();
connection.ConnectionString = TelemarketingTracker.Properties.Settings.Default.TelemarketingDatabaseConnectionString;
TelemarketingDatabaseDataSet ds = new TelemarketingDatabaseDataSet();
// DataTable tbl = new DataTable();
SqlCeDataAdapter adapter = new SqlCeDataAdapter("select * from Calls", connection);
//adapter.InsertCommand = new SqlCeCommand("InsertQuery", connection);
adapter.Fill(ds,"Calls");
DataTable tbl = ds.Tables["Calls"];
//tbl.Columns.Add("caller");
//tbl.Columns.Add("called");
//tbl.Columns.Add("duration");
//tbl.Columns.Add("time");
var row = tbl.NewRow();
row[1] = Convert.ToString(caller);
row[2] = Convert.ToString(called);
row[3] = Convert.ToString(duration);
row[4] = Convert.ToDateTime(time);
tbl.Rows.Add(row);
adapter.Update(ds, "Calls");
connection.Close();
MessageBox.Show("Database should be updated!");
And please, i'm not intrested in using an SqlCommand as i prefer using DataSet.
Could the problem be related to datatypes of my table? it doesn't show errors to suggest that but i guess this could be the problem. my Table consists of :
ID - int,key
caller - varchar
called - varchar
duration - varchar
time - datetime
EDIT:
Now if i uncomment the insertQuery row i get an unhandled error occured in Syste.Data dll.
Now even if i try to use a regular insert command i get no errors but the database won't update.
if this makes any diffrence after i close the debugging window i see an X next to the local database but it doesn't show any errors.
This is the command i've tried :
using (SqlCeCommand com = new SqlCeCommand("INSERT INTO Calls (caller, called, duration, time) Values(#Caller,#Called,#Duration,#Time)", connection))
{
com.Parameters.AddWithValue("#Caller", row[1]);
com.Parameters.AddWithValue("#Called", row[2]);
com.Parameters.AddWithValue("#Duration", row[3]);
com.Parameters.AddWithValue("#Time", row[4]);
com.ExecuteNonQuery();
}

The Fill() method "Adds or refreshes rows in the DataSet to match those in the data source." The key part of this sentence being "to match those in the data source". The row you're adding gets wiped out when you call Fill() because it's not already in the source.
I'm not positive, but I don't think that you need to even call Fill() if you're only adding new records and not worried about modifying/removing existing ones. If you do need to call it though, it would obviously need to be moved before any new record insertions you make.

Try something similar to this..
string dbfile = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\TelemarketingDatabase.sdf";
SqlCeConnection connection = new SqlCeConnection("datasource=" + dbfile);
TelemarketingDatabaseDataSet ds = new TelemarketingDatabaseDataSet();
SqlCeDataAdapter adapter = new SqlCeDataAdapter();
string qry = #"select * from Calls";
da.SelectCommand = new SqlCommand(qry, connection);
SqlCommandBuilder cb = new SqlCommandBuilder(adapter);
adapter.Fill(ds,"Calls");
DataTable tbl = ds.Tables["Calls"];
var row = tbl.NewRow();
row[0] = caller;
row[1] = called;
row[2] = duration;
row[3] = Convert.ToDateTime(time);
tbl.Rows.Add(row);
adapter.Update(ds,"Calls");
See the example here http://www.java2s.com/Code/CSharp/Database-ADO.net/UseDataTabletoupdatetableinDatabase.htm

Well in the end i didn't manage to solve this, instead i used a remote database and regular sql commands.
Thanks for those who helped!

just want to share this even the if the question is old
using System;
using System.IO; //needed for path.getdirectoryname() and directory.getcurrentdirectory()
string path = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory()));
AppDomain.CurrentDomain.SetData("DataDirectory", path);
Directory.GetcurrentDirectory() will output "C:/..projectname/bin/debug" which is where the temporary database.mdf is located
by using Path.GetDirectoryName(Directory.GetcurrentDirectory()) it will give the directory of the current directory thus moving one location back
"C:/..projectname/bin"
then use it again
Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())) will give you the location of the root database in your project folder
"C:/..projectname"
then just use AppDomain.CurrentDomain.SetData()

Related

Missing column from access database in datagridview

I have an access database in a windows forms application which I use to populate datagridviews. However one of the columns never displays and when specified within the select statement it returns a "No value given for one or more required parameters"
Here is the current code
string select_Schedules = "SELECT * FROM Schedules";
conn = new OleDbConnection(constr);
conn.Open();
ds = new DataSet();
adap = new OleDbDataAdapter();
cmd = new OleDbCommand(select_Schedules, conn);
adap.SelectCommand = cmd;
adap.Fill(ds);
dataGridView1.DataSource = ds.Tables[0].DefaultView;
dataGridView2.DataSource = ds.Tables[0].DefaultView;
dataGridView3.DataSource = ds.Tables[0].DefaultView;
dataGridView4.DataSource = ds.Tables[0].DefaultView;
conn.Close();
The column is indeed contained within the table
This what the "SELECT * " query returns
as seen the Show_Date column is missing. When specified through
SELECT Show_Date FROM Schedules
it returns the error as previously mentioned.
As Steve pointed out I had an old connection string in this specific form. A simple mistake indeed.
I bet that you are not looking at the same database that you are querying. Check your connectionstring. Did you use DataDirectory shortcut? – Steve
So my problem has been solved. Thank you.

Update using MySqlDataAdapter doesn't work

I am trying to use MySqlDatAdapter to update a MySql table. But, the table never updates!!! I did this before but with SQL server. Is there anything else that is specific to MySql that I am missing in my code?
DataTable myTable = new DataTable("testtable");
MySqlConnection mySqlCon = new MySqlConnection(ConfigurationManager.ConnectionStrings["DBConStr"].ConnectionString);
MySqlCommand mySqlCmd = new MySqlCommand("SELECT * FROM testtable WHERE Name = 'Tom'");
mySqlCmd.Connection = mySqlCon;
MySqlDataAdapter adapter = new MySqlDataAdapter(mySqlCmd);
MySqlCommandBuilder myCB = new MySqlCommandBuilder(adapter);
adapter.UpdateCommand = myCB.GetUpdateCommand();
mySqlCon.Open();
adapter.Fill(myTable);
myTable.Rows[0]["Name"] = "Was Tom";
myTable.AcceptChanges();
adapter.Update(myTable);
mySqlCon.Close();
Thanks
Remove myTable.AcceptChanges() before the update. Othwerwise that will set all rows RowState to Unchanged, hence the DataAdapter will not know that something was changed.
adapter.Update(myTable) will call AcceptChanges itself after the update is finished.
So...
myTable.Rows[0]["Name"] = "Was Tom";
//myTable.AcceptChanges();
adapter.Update(myTable);
My some one need to look into the following solution; In other scenario people may need different solution. Even Don't do any manipulation with Datatable when you Debug at Run-time like this,
myTable.GetChanges(); // Return Any of Chnages Made without applying myTable.Accepchanges()
myTable.GetChanges(DataRowState.Added); // Return added rows without applying myTable.Accepchanges()
myTable.GetChanges(DataRowState.Deleted);
myTable.GetChanges(DataRowState.Detached);
myTable.GetChanges(DataRowState.Modified);
myTable.GetChanges(DataRowState.Unchanged);
You may get Data According to the above commands. So better try to debug before you pass the datatable to update or insert or delete command.
If myTable.GetChanges() return null then you can SetAdded() or SetModified() back to your DataTable;
foreach(DataRow row in myTable.Rows)
{
row.SetAdded(); // For Insert Command
row.SetModified(); // For Update Command
}

Problem with ADO.NET UPDATE code

Could somebody take a quick peek at my ado.net code? I am trying to update the row from a dataset, but it just isn't working. I am missing some elemental piece of the code, and it is just eluding me. I have verified that the DataRow actually has the correct data in it, so the row itself is accurate.
Many thanks in advance.
try
{
//basic ado.net objects
SqlDataAdapter dbAdapter = null;
DataSet returnDS2 = new DataSet();
//a new sql connection
SqlConnection myConn = new SqlConnection();
myConn.ConnectionString = "Server=myserver.mydomain.com;"
+ "Database=mydatabase;"
+ "User ID=myuserid;"
+ "Password=mypassword;"
+ "Trusted_Connection=True;";
//the sqlQuery
string sqlQuery = "select * from AVLUpdateMessages WHERE ID = 21";
//another ado.net object for the command
SqlCommand cmd = new SqlCommand();
cmd.Connection = myConn;
cmd.CommandText = sqlQuery;
//open the connection, execute the SQL statement and then close the connection.
myConn.Open();
//instantiate and fill the sqldataadapter
dbAdapter = new SqlDataAdapter(cmd);
dbAdapter.Fill(returnDS2, #"AVLUpdateMessages");
//loop through all of the rows; I have verified that the rows are correct and returns the correct data from the db
for (int i = 0; i <= returnDS2.Tables[0].Rows.Count - 1; i++)
{
DataRow row = returnDS2.Tables[0].Rows[i];
row.BeginEdit();
row["UpdatedText"] = #"This is a test...";
row.EndEdit();
}
//let's accept the changes
dbAdapter.Update(returnDS2, "AVLUpdateMessages");
returnDS2.AcceptChanges();
myConn.Close();
}
I think you need an update query in your data adapter. I know, this sucks... Alternatively you can use CommandBuilder class to automatically generate queries for CRUD operations.
example at: http://www.programmersheaven.com/2/FAQ-ADONET-CommandBuilder-Prepare-Dataset
You might be able to use SqlCommandBuilder to help out. After the Fill call, add the following statement. That will associate a command builder with the data adapter and (if there is a primary key available) it should generate the update statement for you. Note that there is some expense behind the command builder. It may not be much relative to everything else, but it does involve looking at schema information (to get primary key information, field names, field types, etc.) for the table and generating INSERT, DELETE, and UPDATE statements involving all fields in the table.
SqlCommandBuilder cb = new SqlCommandBuilder(dbAdapter);
Wait, why not something like
update AVLUpdateMessages set UpdatedText = 'This is a test...' where id = 21
If you're picking through all the rows of a table to update one at a time, you're probably doing it wrong. SQL is your friend.

Cannot commit DataSet changes to database

I've written a small form that reads the data from a database table (SQL CE 3.5) and displays it in a DataGridView control. This works fine. I then modified it to make a change to the data before displaying it, which also seems to work fine with the exception that it doesn't seem to actually commit the changes to the database. The code is as follows:
using (SqlCeConnection conn = new SqlCeConnection(
Properties.Settings.Default.Form1ConnectionString
)) {
conn.Open();
using (SqlCeDataAdapter adapter = new SqlCeDataAdapter(
"SELECT * FROM People", conn
)) {
//Database update command
adapter.UpdateCommand = new SqlCeCommand(
"UPDATE People SET name = #name " +
"WHERE id = #id", conn);
adapter.UpdateCommand.Parameters.Add(
"#name", SqlDbType.NVarChar, 100, "name");
SqlCeParameter idParameter = adapter.UpdateCommand.Parameters.Add(
"#id", SqlDbType.Int);
idParameter.SourceColumn = "id";
idParameter.SourceVersion = DataRowVersion.Original;
//Create dataset
DataSet myDataSet = new DataSet("myDataSet");
DataTable people = myDataSet.Tables.Add("People");
//Edit dataset
adapter.Fill(myDataSet, "People");
people.Rows[0].SetField("name", "New Name!");
adapter.Update(people);
//Display the table contents in the form datagridview
this.dataGridView1.DataSource=people;
}
}
The form displays like so:
Looking at the table via Visual Studio's Server Explorer however, doesn't show any change to the table.
What am I doing wrong?
I found it. It took days but I found it.
Properties.Settings.Default.Form1ConnectionString is "Data Source=|DataDirectory|\Form1.sdf". The update works if I replace the automatically generated "|DataDirectory|" with the actual path. Oddly enough reading from the database works either way.
Shouldn't the update line be
adapter.Update(myDataSet, "People")
I would make sure the DataSet believes it's been changed. Invoke DataSet.HasChanges (returns bool) and DataSet.GetChanges, which returns a delta of the DataSet from the original.
Have you also tried this against Sql Server Express just to eliminate any issues with the CE data adapter?

Question on updating/inserting a datatable in a dataset

I need to open a connection to SQL database and read a subset of a table and either update a record if exists or insert if not found. Having truoble updating
SqlConnection conn = new SqlConnection(ConnectionStrings.PgenIntranet.SqlClientConnectionString);
SqlDataAdapter indicators = new SqlDataAdapter();
string sql = "SELECT * FROM BusinessApplications.tbl_WPI_Site_Indicators where Year = '" + year +
"' and Month = '" + month + "' and PlantId = " + site.ID;
indicators.SelectCommand = new SqlCommand(sql, conn);
SqlCommandBuilder cb = new SqlCommandBuilder(indicators);
indicators.UpdateCommand = cb.GetUpdateCommand();
DataSet ds = new DataSet();
indicators.Fill(ds, "indtable");
DataTable indtable = ds.Tables["indtable"];
// this logic not working
if (indtable.Rows.Count == 0) { indtable.NewRow(); }
DataRow dr = indtable.NewRow();
/// not sure how to make this work
indtable[1]["PlantId"] = site.ID;
dr["PlantId"] = site.ID;
It's been a while since I've used DataSets/DataTables/DataRows, but I think you're close. If I remember correctly, you'll need to create a new row object like you do here:
DataRow dr = indtable.NewRow();
Then populate that row with your data, also similar to how you were doing it:
dr["PlantId"] = site.ID;
Then finally add that row to the rows collection in the DataTable. (You'll want to double-check if your DataTable instance is actually the DataTable in the Tables collection on the DataSet, I don't recall the specifics. It may be safer to reference the Tables collection directly rather than put it in its own object.)
Note that this does not add the row back to the database. It just adds it to the DataTable instance. You'll need to update back to the database accordingly. And this setup that you have here is a bit... messy... so I have no quick answer for that. Since you're just using plain old ADO then I guess you'll need to create an update command and populate it and run it against the connection accordingly.
In doing so, please take care to fix SQL injection vulnerabilities like the one you have there :)
Don't forget to add your new row to the table, then call update...
indtable.Rows.Add(dr);
ds.Update();

Categories