Android Question SQL Server JdbcSQL remote connection problem

Bladimir Silva Toro

Active Member
Licensed User
Longtime User
I have been connected to SQL Server using JdbcSQL.

Something very funny happens to me in debug mode, the record is added correctly, but when I compile in Release mode it doesn't work.

Log :

--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
** Service (starter) Destroy (ignored)**
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Error occurred on line: 81 (Main)
java.lang.NullPointerException: Attempt to invoke interface method 'java.sql.PreparedStatement java.sql.Connection.prepareStatement(java.lang.String)' on a null object reference
at anywheresoftware.b4j.objects.SQL.ExecNonQuery2(SQL.java:194)
at b4a.example.main._btnagregar_click(main.java:454)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:180)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:6608)
at android.view.View.performClickInternal(View.java:6585)
at android.view.View.access$3100(View.java:785)
at android.view.View$PerformClick.run(View.java:25921)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6864)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)


I leave the code in B4A and attached the project.

B4X:
Region  Project Attributes
    #ApplicationLabel: Remoto SQL Server
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: True
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

'libreria para la conexion a SQl Server
#AdditionalJar: jtds-1.3.1
#BridgeLogger: true

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Public mysql As JdbcSQL
    Private driver As String = "net.sourceforge.jtds.jdbc.Driver"
    Private jdbcUrl As String = "jdbc:jtds:sqlserver://10.72.132.51/BD_EMPRESA"
    Private Username As String = "Adsi"
    Private Password As String = "12345"
    Public Cursor As JdbcResultSet
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private TxtNombre As B4XFloatTextField
    Private TxtSalario As B4XFloatTextField
    Private B4XTable1 As B4XTable
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("frminicio")
    'añado las columna con el tipo de datos
    B4XTable1.AddColumn("ID",B4XTable1.COLUMN_TYPE_NUMBERS)
    B4XTable1.AddColumn("Nombre",B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Salario",B4XTable1.COLUMN_TYPE_NUMBERS)
End Sub

Sub Activity_Resume
  
End Sub

Sub Activity_Pause (UserClosed As Boolean)
  
End Sub

Sub TraerDatos As ResumableSub
    Dim Data As List
    Data.Initialize
    mysql.InitializeAsync("mysql", driver, jdbcUrl, Username, Password)
    Dim sf As Object = mysql.ExecQueryAsync("mysql", "SELECT * FROM Empleados WHERE id > ?", Array(1))
    Wait For (sf) mysql_QueryComplete (Success As Boolean, Crsr As JdbcResultSet)
    If Success Then
        Do While Crsr.NextRow
            Dim row(3) As Object
            row(0)= Crsr.GetInt("ID")
            row(1)= Crsr.GetString("Nombre")
            row(2)= Crsr.GetInt("Salario")
            Data.Add(row)
        Loop
        Crsr.Close
        B4XTable1.SetData(Data)
      
    End If
    Return Success
End Sub

Sub BtnAgregar_Click
    mysql.InitializeAsync("mysql", driver, jdbcUrl, Username, Password)
    Dim nom As String=TxtNombre.Text
    Dim sal As Int =TxtSalario.Text
    mysql.ExecNonQuery2("INSERT INTO Empleados (nombre,salario) VALUES (?, ?)", Array As String (nom, sal))
    MsgboxAsync("Empleado Agregado", "Felicitaciones!!!")
    Wait For (TraerDatos) Complete (Result As Boolean)
End Sub

Sub BtnEditar_Click
  
End Sub

Sub BtnEliminar_Click
  
End Sub

Sub B4XTable1_CellClicked (ColumnId As String, RowId As Long)
  
End Sub


Thank you very much to those who can help me.
 

Attachments

  • RemotoMySQL.zip
    40.4 KB · Views: 169

Albert Kallal

Active Member
Licensed User
Actually, I am not too surprised. Remember in non debug mode, your code going to run much better, and much faster.

You have this:
B4X:
    mysql.InitializeAsync("mysql", driver, jdbcUrl, Username, Password)
    Dim nom As String=TxtNombre.Text
    Dim sal As Int =TxtSalario.Text
    mysql.ExecNonQuery2("INSERT INTO Empleados (nombre,salario) VALUES (?, ?)", Array As String (nom, sal))
Note the initialize "Async" first line. "Async" means the code will NOT WAIT, but keep on running to the next lines of code EVEN if the Initialize has not finished. So in debug mode, the code runs slow enough for the initialize to finish - but in full speed warp drive mode, then the NonQuery likely tries to run before that first line of code is even finished.

You could use:
mysql.Initalize() , but then that forces the code to wait. (and I believe you have to include the user/password in the connection string).

So, you likley want this:
B4X:
    mysql.InitializeAsync("mysqlWAIT", driver, jdbcUrl, Username, Password)
    Wait For mysqlWAIT_Ready (Success As Boolean)
    If Success = True then
     bla bla bla
So ether use mysql.Intialize(), but really, it better yet to use the "ansync" initialize as above, and make sure your code waits until the actual initialize code is actually done.

The above is a guess by just a quick look at the code - but try the above idea.

Regards,
Albert D. Kallal
Edmonton, Alberta Canada
 
Upvote 0
Top