I have a User-Defined Function which returns a String type value..
Inside the function, I am invoking the SQL Query using WAIT
A broad template of the code is shown below:
Code Template:
Public Sub myfunc(pid As Long) As String
Dim SenderFilter As Object
dim mySqlQuery as String
mySQLQuery="SELECT ..."
SenderFilter=Starter.SQL.ExecQueryAsync("SQL", mySQLQuery,Null)
Wait For (SenderFilter) SQL_QueryComplete (Success As Boolean, RS As ResultSet)
If Success Then
Return(RS.GetString(<Field Name>))
Else
Log(LastException)
End If
End Sub
However, the IDE gives compile error saying that
'Error description: Resumable subs return type must be ResumableSub (or none)'
My Doubt:
How to write a user-defined-function returning a datatype but which is a resumable sub in it...
Change the return type to ResumableSub, return the value as normal with 'Return whatever' and call it using Wait For. You can nest ResumableSubs as follows.
B4X:
Sub Button1_Click
Wait For (test1) Complete (val As String)
Log(val)
End Sub
Private Sub test1 As ResumableSub
Wait For (test2) Complete (val As String)
Return val
End Sub
Private Sub test2 As ResumableSub
Sleep(0)
Return "Result"
End Sub
Remember that that a call to Sleep or Wait For in a resumable sub causes the code flow to return to the parent. Example: Sub Button1_Click Sum(1, 2) Log("after sum") End Sub Sub Sum(a As Int, b As Int) Sleep(100) 'this will cause the code flow to return to the parent Log(a + b) End Sub...
Change the return type to ResumableSub, return the value as normal with 'Return whatever' and call it using Wait For. You can nest ResumableSubs as follows.
B4X:
Sub Button1_Click
Wait For (test1) Complete (val As String)
Log(val)
End Sub
Private Sub test1 As ResumableSub
Wait For (test2) Complete (val As String)
Return val
End Sub
Private Sub test2 As ResumableSub
Sleep(0)
Return "Result"
End Sub
Remember that that a call to Sleep or Wait For in a resumable sub causes the code flow to return to the parent. Example: Sub Button1_Click Sum(1, 2) Log("after sum") End Sub Sub Sum(a As Int, b As Int) Sleep(100) 'this will cause the code flow to return to the parent Log(a + b) End Sub...
1) I get the warning 'Not all code paths return a value'
How can that be removed ?
2) I got a CursorIndexOutOfBoundsException error in SQLLITE when I did not use Do While Rs.Nextrow ... Loop ...
This is despite the fact that you know there will be only 1 record match (For example, you want the employee name given an employee id and you know there will be only one record match. You are the database designer and you have ensured primary key validation on the employee id and so you know that there will be only one unique entry for every employee_id) and there was no need to have a loop...
Is this the right way to FIRE EVERY SQLLITE query (even if the database designer knows fully well that there will be only 1 record match) ?
Not from that code fragment you quoted above. If you mean your original fragment in the first post you have a Sub with a Return statement in a conditional block but not also at the end of the Sub if the conditional isn't met.
B4X:
Public Sub myfunc(pid As Long) As String
'... some code
If Success Then
Return(RS.GetString(<Field Name>))
Else
Log(LastException)
' Need a Return something here'
End If
' or here
End Sub
Remember that that a call to Sleep or Wait For in a resumable sub causes the code flow to return to the parent. Example: Sub Button1_Click Sum(1, 2) Log("after sum") End Sub Sub Sum(a As Int, b As Int) Sleep(100) 'this will cause the code flow to return to the parent Log(a + b) End Sub...
The "do while" is not important. Calling rs.NextRow is a must.
Correct code:
B4X:
Wait For (SenderFilter) SQL_QueryComplete (Success As Boolean, RS As ResultSet)
If Success Then
rs.NextRow 'must be at least one record
Dim res As SAtring = RS.GetString(<Field Name>)
rs.Close '<------
Return res
Else
Log(LastException)
End If
Return "" 'or any other value that you like to represent an error
Not from that code fragment you quoted above. If you mean your original fragment in the first post you have a Sub with a Return statement in a conditional block but not also at the end of the Sub if the conditional isn't met.
B4X:
Public Sub myfunc(pid As Long) As String
'... some code
If Success Then
Return(RS.GetString(<Field Name>))
Else
Log(LastException)
' Need a Return something here'
End If
' or here
End Sub
Looks fine to me but I don't use SQL so I might be wrong
The "do while" is not important. Calling rs.NextRow is a must.
Correct code:
B4X:
Wait For (SenderFilter) SQL_QueryComplete (Success As Boolean, RS As ResultSet)
If Success Then
rs.NextRow 'must be at least one record
Dim res As SAtring = RS.GetString(<Field Name>)
rs.Close '<------
Return res
Else
Log(LastException)
End If
Return "" 'or any other value that you like to represent an error
Remember that that a call to Sleep or Wait For in a resumable sub causes the code flow to return to the parent. Example: Sub Button1_Click Sum(1, 2) Log("after sum") End Sub Sub Sum(a As Int, b As Int) Sleep(100) 'this will cause the code flow to return to the parent Log(a + b) End Sub...