Adapter.Update

jsurpless

Well-known member
Joined
Jul 29, 2008
Messages
144
Programming Experience
Beginner
Hi all

I've successfully used the following code to populate a datatable from my MS Access database

VB.NET:
strMSAccess_Connection_SQL = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDatabaseFilePath & ";Persist Security Info=True"
MSAccess_Connection = New OleDbConnection(strMSAccess_Connection_SQL)

MSAccess_Connection.Open()

strDatabaseTable_SQL = "SELECT * FROM [" & strDatabaseTable & "]"

If (strDatabaseTable_SQLWhere <> "") Then

  strDatabaseTable_SQL = strDatabaseTable_SQL & " " & strDatabaseTable_SQLWhere

End If

MSAccess_Database_Adapter = New OleDbDataAdapter(strDatabaseTable_SQL, MSAccess_Connection)
       MSAccess_Database_Adapter.Fill(MSAccess_DatabaseTable)

Now, I'd like to use a similar method to push changes back to the database, having done them to the datatable...

I was thinking I'd be able to do something like this but it doesn't seem to work...

VB.NET:
strMSAccess_Connection_SQL = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDatabaseFilePath & ";Persist Security Info=True"
MSAccess_Connection = New OleDbConnection(strMSAccess_Connection_SQL)

MSAccess_Connection.Open()

strDatabaseTable_SQL = "SELECT * FROM [" & strDatabaseTable & "]"

If (strDatabaseTable_SQLWhere <> "") Then

  strDatabaseTable_SQL = strDatabaseTable_SQL & " " & strDatabaseTable_SQLWhere

End If

MSAccess_Database_Adapter = New OleDbDataAdapter(strDatabaseTable_SQL, MSAccess_Connection)

MSAccess_Database_Adapter.AcceptChangesDuringUpdate = True

MSAccess_Database_Adapter.Update(MSAccess_DatabaseTable)

Any thoughts?
 
By ensuring that your SQL looks like:

"UPDATE [table name] SET ..."

That makes sense but if I'm not explicitly setting the .UpdateCommand but am instead allowing .Update to build it automatically - how would I do it with this in mind?
 
Here's the code I'm using for the OleDbDataAdapter

VB.NET:
strMSAccess_Connection_SQL = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDatabaseFilePath
MSAccess_Connection = New OleDbConnection(strMSAccess_Connection_SQL)
MSAccess_Connection.Open()

strDatabaseTable_SQL = "SELECT * FROM [" & strDatabaseTable & "]"

MSAccess_Database_Adapter = New OleDbDataAdapter(strDatabaseTable_SQL, MSAccess_Connection)

It seems that I'm doing what you mentioned...
 
When using the .Update function, allowing .NET to build the SQL statement dynamically - I get an UPDATE syntax error...
 
Show the code used to create and assign the UpdateCommand, and also the generated command text
 
What I'm saying that I am not explicitly specifying the .UpdateCommand... as I understand it, .Update will automatically generate that itself (if not specified)...

I'm making the changes to the DataTable and then using .Update to apply them to the database... no assignment of .UpdateCommand

Here's the code

VB.NET:
Dim MSAccess_DatabaseTable_Changes As DataTable

MSAccess_DatabaseTable_Changes = MSAccess_DatabaseTable.GetChanges

If Not IsNothing(MSAccess_DatabaseTable_Changes) Then

  MSAccess_Database_Builder = New OleDbCommandBuilder(MSAccess_Database_Adapter)

  MSAccess_Database_Adapter.Update(MSAccess_DatabaseTable_Changes)

End If

On a different note, I also get an 'INSERT INTO' error when using this code...

VB.NET:
Dim New_DatabaseDrawing_Table_Row As DataRow = DatabaseDrawing_Table.NewRow()

New_DatabaseDrawing_Table_Row(c_Database.DrawingFileName_Field) = strAutoCADFile

DatabaseDrawing_Table.Rows.Add(New_DatabaseDrawing_Table_Row)

once I process it through the above code...
 
What I'm saying that I am not explicitly specifying the .UpdateCommand... as I understand it, .Update will automatically generate that itself (if not specified)...

Er, yes.. Though you need to tell the CommandBuilder what your quote prefix and suffix were for the table names, otherwise it generates statements like:

INSERT INTO table ...

instead of

INSERT INTO [table name] ...


See here:
VB.NET:
        Dim oconn As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\YOUR.mdb;Persist Security Info=True")

        Dim ocmd As New OleDb.OleDbCommand("CREATE TABLE [Table Name Spaces] (MyID LONG CONSTRAINT PK_MyID PRIMARY KEY, FirstName TEXT(20), LastName Text(20) )", oconn)
        ocmd.Connection.Open()
        ocmd.ExecuteNonQuery()

        Dim oda As OleDb.OleDbDataAdapter
        oda = New OleDb.OleDbDataAdapter("SELECT * FROM [Table Name Spaces]", oconn)

        Dim ocb As New OleDb.OleDbCommandBuilder(oda)
        ocb.QuotePrefix = "["
        ocb.QuoteSuffix = "]"
        'oda.InsertCommand = ocb.GetInsertCommand()
        'oda.UpdateCommand = ocb.GetUpdateCommand()
        'oda.DeleteCommand = ocb.GetDeleteCommand()

        Dim ds As New DataSet
        oda.Fill(ds)

        ds.Tables(0).Rows.Add(1, "John", "Smith")

        oda.Update(ds)

        ds.Tables(0).Rows(0)("FirstName") = "Jane"

        oda.Update(ds)

        ds.Tables(0).Rows(0).Delete()

        oda.Update(ds)

Note if you dont set the InsertCommand etc, then DataAdapter will get one each time from the command builder but never assign it internally; it can be awfully confusing to look at a DA and see no insert command, yet still find it generating error messages like there is one

If you set them yourself, you'd can see the generated SQLs; this probably would have made it more apparent that there were syntax errors.

Most important note is that you need to set the QuotePrefix and QuoteSuffix propeties of the command builder
 
OK, that QuotePrefix and Suffix seem to have done the trick...

I understand your recommendation about setting the .UpdateCommand, etc but when it just looks like this

VB.NET:
UPDATE [Table1] SET [TITLE_2] = ?, etc, etc

It doesn't seem to mean anything so why bother?

BTW, thanks so much for your continued help... it's been much appreciated...
 
Another quick question - before starting this whole process, I'd like to verify that the datatable does, in fact, have a primary key...

How would I do this?

Thanks again!
 
OK, that QuotePrefix and Suffix seem to have done the trick...

I understand your recommendation about setting the .UpdateCommand, etc but when it just looks like this

VB.NET:
UPDATE [Table1] SET [TITLE_2] = ?, etc, etc

It doesn't seem to mean anything so why bother?

BTW, thanks so much for your continued help... it's been much appreciated...

Not quite sure I understand the question, and I havent read the code written by Microsoft on how the DataAdapter works but I suspect that if there is an If UpdateCommand Is Nothing Then commandBuilder.GetUpdateCommand()

And maybe commandbuilder caches the last update command it built so to save the CPU cycles.. Or maybe not.. However, if we set the UC, then we can be sure it wont be generated many times needlessly.
 
Another quick question - before starting this whole process, I'd like to verify that the datatable does, in fact, have a primary key...

How would I do this?

Thanks again!

You can probably just catch the exception from the commandbuilder; it will error out if there is no PK..

Alternately, GetSchema may give you the info; google it :)
 
Back
Top