I am trying to retrieve some data from a disconnected SQl Server database via a DataSet and then Insert the contents of this dataSet into a local Access database.
The first part is working just fine. I'm using the following code:
String *ConnectionString = S"Data Source=notreally.here.com;Initial Catalog=MyForums;User Id=user;Password=fake;";
SqlConnection * conSql = new SqlConnection(ConnectionString);
SqlCommand *sqlSelect = new SqlCommand();
sqlSelect->CommandText = String::Concat(S"SELECT * FROM Posts WHERE ForumID=",
ForumID.ToString(), S" AND Sent>'", Since.ToString(), S"' ORDER BY Sent");
sqlSelect->Connection = conSql;
SqlDataAdapter *dataAdapter = new SqlDataAdapter();
dataAdapter->SelectCommand = sqlSelect;
DataSet *ds = new DataSet();
dataAdapter->Fill(ds);
The DataSet Fills up with the correct data. So next I create an OleDb DataAdapter to store in the local Access database like so:
OleDbConnection *oleConnection = new OleDbConnection(S"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=.\\hsf.mdb");
OleDbCommand *oleInsert = new OleDbCommand();
oleInsert->CommandText = S"INSERT INTO Posts VALUES (?,?,?,?)");
oleInsert->Connection = oleConnection;
oleInsert->Parameters->Add(new OleDbParameter(S"@PostID", OleDbType::BigInt, 8, S"PostID"));
oleInsert->Parameters->Add(new OleDbParameter(S"@ForumID", OleDbType::BigInt, 8, S"ForumID"));
oleInsert->Parameters->Add(new OleDbParameter(S"@ThreadID", OleDbType::BigInt, 8, S"ThreadID"));
oleInsert->Parameters->Add(new OleDbParameter(S"@ReplyToID", OleDbType::BigInt, 8, S"ReplyToID"));
OleDbDataAdapter *accessAdapter = new OleDbDataAdapter();
accessAdapter->InsertCommand = oleInsert;
accessAdapter->Update(ds);
When this executes, nothing happens. No error is generated but the Update method returns 0 and nothing is written to the database.
I have found that if I manually create a new DataSet and write in the appropriate columns and row values, that will Update just fine. So I think the problem lies within the DataSet itself and not OleDb code.
Can anyone suggest what is wrong, or am I going about this in the wrong way enitrely? Thanks.
A dataset has a number of versions of each data row. These are described by the System::Data::DataRowVersi
When you modify a row, the original version stays the same, but the proposed version shows the changes you have made. When you wish to update the database with the changes, the Update method will look to see if anything has changed in the dataset since it was last declared current. It determines if there are changes by looking at the proposed version of each row. When it sees the changes, it calls the appropriate command: UpdateCommand if the change requires an update statement; InsertCommand if the change requires a new row in the database; and the DeleteCommand if your changes deletes a row in the dataset and database.
This is half the story. The other half is that your Update, Delete, and Insert commands must use the parameters, and you must specify which datarow version the parameter is filled from.
I believe this is the problem with your example above. The parameters you have specified for the oleInsert command do not specify the row version to be filled from. Since your dataset does not appear to have any changes, nothing is going to be updated. If there were changes to reflect into your Access database, which version of the dataset's rows would the parameters fill from?
For your case, your oleInsert command might need to read like this example:
oleInsert->Parameters->Add
After you have completed the Update, if there have been any changes to the dataset, you need to "Accept" the changes so that a repeated call to Update does not try to send the changes again. This is done with the AcceptChanges method which can be called on the dataset object or the table object.
Hope that helps.