DBUtils Update

Tom Law

Active Member
Licensed User
Longtime User
I am having a problem getting my program to save modified records (it uses an SQLite data file and is accessed via the DBUtils routine). Data can be read OK from the table and field values can be modified without problem however the save routine is obviously failing.

Could someone confirm whether DBUtils.UpdateRecord needs to be used on a field by field basis or does it update the entire record when called once (not sure if I'm using it correctly).
 

devlei

Active Member
Licensed User
Longtime User
Although I have not really used the DBUtils.UpdateRecord, it looks like it does only one field at a time. You must make sure your WhereFieldEquals is correct otherwise it will not save correctly.

I know that using the DBUtils helps one to get going quicker, but it will be worth your while understanding how to do the basic database functions (Update, Insert, Delete etc) apart from DBUtils.

For example, the ExecNonQuery2 command makes it very easy to save/update all your fields in one line of code.
 
Upvote 0

Tom Law

Active Member
Licensed User
Longtime User
Hi Gents, thank you for your input - it is much appreciated. I have database experience (Microsoft Access) going back up to 20 years in VB but this is new to me (must be getting too old now).

eps - I am assuming that the InsertMaps function is for entering a new record into the database (please correct me if that is wrong). What I am trying to do is to update an exiting record. If you have an example of a database using the Update routine in DBUtils it would help enormously.

devlei - You may have a point about the Wherefieldequals array - I will pay further attention to that and see if I have any errors there. I also agree with you that it looks like this routine only updates one field at a time - although if that is the case it seems a strange implementation compared to the way I have worked previously.

Tom
 
Upvote 0

devlei

Active Member
Licensed User
Longtime User
Tom, I have also recently started with B4A having had some Access & VB experience and have found that getting to grips with SQL statements has made database things much simpler for me.

For quick help with SQL look at SQL Introduction.

Dave
 
Upvote 0

devlei

Active Member
Licensed User
Longtime User
Klaus, as a result of reading your post I realised that I did not have the latest Beginners Guide. The version I was using did not have any info under the Database section. I have browsed through this chapter in the latest version and it looks very good. Well done - I was just a few months to early to get the benefit of it.
 
Upvote 0

Tom Law

Active Member
Licensed User
Longtime User
Hi Klaus,

Thanks for that, unfortunately the version I have does not show the use of DBUtils (which is what I am trying to use) - do you know of an example that uses the update function in DBUtils or have I got the wrong version of the beginners guide?


Many thanks
Tom

Hi Tom,

If you want to have a look at SQLite, you could have a look at chapter 12.4 Database example in the Beginner's Guide there are some explanations and an example program.

Best regards.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I intentionaly wrote "If you want to have a look at SQLite . . ."
because there is no example for DBUtils in the Beginner's Guide, only for SQLite.
I felt more concerned to explain the fundamentals of SQLite rather than DBUtils.
I haven't used DBUtils yet, prefering using directly SQLite.

Best regards.
 
Last edited:
Upvote 0

Tom Law

Active Member
Licensed User
Longtime User
Cheers Klaus, appreciate your input,

Would you happen to know who originally wrote the DBUtils module - perhaps I need to contact the author for advice on it's use?

Tom
 
Upvote 0

eps

Expert
Licensed User
Longtime User
Hi Gents, thank you for your input - it is much appreciated. I have database experience (Microsoft Access) going back up to 20 years in VB but this is new to me (must be getting too old now).

eps - I am assuming that the InsertMaps function is for entering a new record into the database (please correct me if that is wrong). What I am trying to do is to update an exiting record. If you have an example of a database using the Update routine in DBUtils it would help enormously.

devlei - You may have a point about the Wherefieldequals array - I will pay further attention to that and see if I have any errors there. I also agree with you that it looks like this routine only updates one field at a time - although if that is the case it seems a strange implementation compared to the way I have worked previously.

Tom

Ah yes, you're right, however if you read all of the thread I posted you would have come to : http://www.b4x.com/forum/basic4andr...android-databases-now-simple-4.html#post61268 which should do what you want.
 
Upvote 0

Tom Law

Active Member
Licensed User
Longtime User
Hi eps, yes that looks promising. I will try it out and let you know how I get on.


Many thanks

Tom
 
Upvote 0

Tom Law

Active Member
Licensed User
Longtime User
It Works ;-)

********** eps - Brilliant suggestion - You were SPOT ON! **********

Thank you for that. I've been struggling with this for ages and your suggestion completely solved the problem.

'UpdateRecordMap' (by Vasper) - This is a subroutine that needs to be incorporated into DBUtils.

And thank you to everyone else who contributed to this thread
 
Upvote 0

Romano Giovanni

New Member
Licensed User
Longtime User
Sorry for my english,
I have implemented an update multiple fields in the table.

In the main program using the syntax.

B4X:
Dim m As Map
m.Initialize
Dim WhereFieldEquals As Map
WhereFieldEquals.Initialize
Dim ListOfMaps As List
ListOfMaps.Initialize
m.Put("field1",Edit1.Text)
m.Put("field2",Edit2.Text)
m.Put("field3",Edit3.Text)
m.Put("field4",Edit4.Text)
ListOfMaps.Add(m)
WhereFieldEquals.Put("Id", IdValue)
DBUtils.UpdateMaps(Main.SQL, "tablename", ListOfMaps, WhereFieldEquals)

Adds the sub "UpdateMaps" in DBUtils

B4X:
'Edits the data to the table.
'ListOfMaps - A list with maps as items. Each map represents a record where the map keys are the columns names
'and the maps values are the values.
'Note that you should create a new map for each record (this can be done by calling Dim to redim the map).
Sub UpdateMaps(SQL As SQL, TableName As String, ListOfMaps As List, WhereFieldEquals As Map)
    Dim sb, columns, values As StringBuilder
    'Small check for a common error where the same map is used in a loop
    If ListOfMaps.Size > 1 AND ListOfMaps.Get(0) = ListOfMaps.Get(1) Then
        Log("Same Map found twice in list. Each item in the list should include a different map object.")
        ToastMessageShow("Same Map found twice in list. Each item in the list should include a different map object.", True)
        Return
    End If
    If WhereFieldEquals.Size > 1 AND WhereFieldEquals.Get(0) = WhereFieldEquals.Get(1) Then
        Log("Same Map found twice in where. Each item in the where should include a different map object.")
        ToastMessageShow("Same Map found twice in where. Each item in the where should include a different map object.", True)
        Return
    End If
    If WhereFieldEquals.Size = 0 Then
        Log("WhereFieldEquals map empty!")
        Return
    End If
    SQL.BeginTransaction
    Try
        For i1 = 0 To ListOfMaps.Size - 1
            sb.Initialize
            values.Initialize
            Dim listOfValues As List
            listOfValues.Initialize
            sb.Append("UPDATE [" & TableName & "] SET ")
            Dim m As Map
            m = ListOfMaps.Get(i1)
            For i2 = 0 To m.Size - 1
                If i2 > 0 Then
                    sb.Append(", ")
                End If
                sb.Append("[").Append(m.GetKeyAt(i2)).Append("] = ?")
                listOfValues.Add(m.GetValueAt(i2))
            Next
            If i1 = 0 Then Log("UpdateMaps (first query out of " & ListOfMaps.Size & "): " & sb.ToString)
            ' where condition          
            sb.Append(" WHERE ")
            For i = 0 To WhereFieldEquals.Size - 1
                If i > 0 Then sb.Append(" AND ")
                sb.Append("[").Append(WhereFieldEquals.GetKeyAt(i)).Append("] = ?")
                listOfValues.Add(WhereFieldEquals.GetValueAt(i))
            Next
            If i1 = 0 Then Log("UpdateMaps (first query out of " & WhereFieldEquals.Size & "): " & sb.ToString)
            SQL.ExecNonQuery2(sb.ToString, listOfValues)
        Next
        SQL.TransactionSuccessful
    Catch
        ToastMessageShow(LastException.Message, True)
        Log(LastException)
    End Try
    SQL.EndTransaction
End Sub

Giovanni
 
Upvote 0

rboeck

Well-Known Member
Licensed User
Longtime User
Sorry for my english,
I have implemented an update multiple fields in the table.

In the main program using the syntax.

B4X:
Dim m As Map
m.Initialize
Dim WhereFieldEquals As Map
WhereFieldEquals.Initialize
Dim ListOfMaps As List
ListOfMaps.Initialize
m.Put("field1",Edit1.Text)
m.Put("field2",Edit2.Text)
m.Put("field3",Edit3.Text)
m.Put("field4",Edit4.Text)
ListOfMaps.Add(m)
WhereFieldEquals.Put("Id", IdValue)
DBUtils.UpdateMaps(Main.SQL, "tablename", ListOfMaps, WhereFieldEquals)

Adds the sub "UpdateMaps" in DBUtils

B4X:
'Edits the data to the table.
'ListOfMaps - A list with maps as items. Each map represents a record where the map keys are the columns names
'and the maps values are the values.
'Note that you should create a new map for each record (this can be done by calling Dim to redim the map).
Sub UpdateMaps(SQL As SQL, TableName As String, ListOfMaps As List, WhereFieldEquals As Map)
    Dim sb, columns, values As StringBuilder
    'Small check for a common error where the same map is used in a loop
    If ListOfMaps.Size > 1 AND ListOfMaps.Get(0) = ListOfMaps.Get(1) Then
        Log("Same Map found twice in list. Each item in the list should include a different map object.")
        ToastMessageShow("Same Map found twice in list. Each item in the list should include a different map object.", True)
        Return
    End If
    If WhereFieldEquals.Size > 1 AND WhereFieldEquals.Get(0) = WhereFieldEquals.Get(1) Then
        Log("Same Map found twice in where. Each item in the where should include a different map object.")
        ToastMessageShow("Same Map found twice in where. Each item in the where should include a different map object.", True)
        Return
    End If
    If WhereFieldEquals.Size = 0 Then
        Log("WhereFieldEquals map empty!")
        Return
    End If
    SQL.BeginTransaction
    Try
        For i1 = 0 To ListOfMaps.Size - 1
            sb.Initialize
            values.Initialize
            Dim listOfValues As List
            listOfValues.Initialize
            sb.Append("UPDATE [" & TableName & "] SET ")
            Dim m As Map
            m = ListOfMaps.Get(i1)
            For i2 = 0 To m.Size - 1
                If i2 > 0 Then
                    sb.Append(", ")
                End If
                sb.Append("[").Append(m.GetKeyAt(i2)).Append("] = ?")
                listOfValues.Add(m.GetValueAt(i2))
            Next
            If i1 = 0 Then Log("UpdateMaps (first query out of " & ListOfMaps.Size & "): " & sb.ToString)
            ' where condition         
            sb.Append(" WHERE ")
            For i = 0 To WhereFieldEquals.Size - 1
                If i > 0 Then sb.Append(" AND ")
                sb.Append("[").Append(WhereFieldEquals.GetKeyAt(i)).Append("] = ?")
                listOfValues.Add(WhereFieldEquals.GetValueAt(i))
            Next
            If i1 = 0 Then Log("UpdateMaps (first query out of " & WhereFieldEquals.Size & "): " & sb.ToString)
            SQL.ExecNonQuery2(sb.ToString, listOfValues)
        Next
        SQL.TransactionSuccessful
    Catch
        ToastMessageShow(LastException.Message, True)
        Log(LastException)
    End Try
    SQL.EndTransaction
End Sub

Giovanni
Whats the difference to UpdateRecord2 ? This subroutine was made to update multiple fields in a record; see:

http://www.b4x.com/android/forum/th...ltiple-field-update-in-dbutils.15188/#content

Greetings
Reinhard
 
Upvote 0
Top