joell
joell

Reputation: 71

VBA run-time error when passing dates to MySQL query

From Excel VBA i connect to MySQL to fetch my_stored_procedure. Working fine except that when I use date filter as parameters to pass to MySQL SP i receive a run-time error.

The date filters are entered by the user in two cells as start-date and end-date. The cells are defined defined as ranges dateFrom and dateTo.

So I'm using these ranges to pass on to mySql rs, but VBA throws back:

Run-time error '-2147217900 (80040e14)'

You have an error in MySQL syntax; check the manual that corresponds to your MYSQL server version... 'my_stored_procedure '2015-10-01', '2015-10-30'' at line 1.

Below is my VBA code:

        Const ConnStr As String = "Driver={MySQL ODBC 5.3 ANSI Driver};Server=0.0.0.0;Database=db;User=user;Password=pw;Option=3;PORT=3306;Connect Timeout=20;"

Function MySqlCommand(strSql As String) As Variant
    Dim conMySQL
    Set conMySQL = CreateObject("ADODB.Connection")
    Set cmd = CreateObject("ADODB.Command")
    conMySQL.ConnectionString = ConnStr
    conMySQL.Open
    Set cmd.ActiveConnection = conMySQL
    cmd.CommandText = strSql
    ReturnValue = cmd.Execute
    conMySQL.Close
End Function

Function MySqlRS(strSql As String) As ADODB.Recordset
    Dim conMySQL
    Set conMySQL = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    conMySQL.ConnectionString = ConnStr
    conMySQL.Open
    Set rs.ActiveConnection = conMySQL
    rs.Open strSql
    Set MySqlRS = rs
End Function
_____
Public Sub fetchReport()

Dim rs As ADODB.Recordset
    Set rs = MySqlRS("my_stored_procedure '" & Format(Range("dateFrom"), "yyyy-mm-dd") & "' ,'" & Format(Range("dateTo"), "yyyy-mm-dd") & "' ")
Dim hd As Integer


    If Not rs.EOF Then
            For hd = 0 To rs.Fields.Count - 1
                Worksheets("data").Cells(1, hd + 1).Value = rs.Fields(hd).Name  'insert column headers
            Next

        Sheets("data").Range("A2").CopyFromRecordset rs  'insert data
        Sheets("data").Range("A1").CurrentRegion.Name = "rsRange"  'set named range for pivot
    End If

ActiveWorkbook.RefreshAll

End Sub

And here is my SP syntax:

CREATE DEFINER=`user`@`%` PROCEDURE `my_stored_procedure`
(
in fromDate date,
in toDate date
)
BEGIN
SELECT ...
WHERE dateColumn >= fromDate AND dateColumn <= toDate 
END

Any help is appreciated.

Joel

Upvotes: 0

Views: 1438

Answers (2)

user5412293
user5412293

Reputation:

Hi try this and see how it goes

Option Explicit
Const strCONNECTION As String = "Driver={MySQL ODBC 5.3 ANSI Driver};Server=0.0.0.0;Database=db;User=user;Password=pw;Option=3;PORT=3306;Connect Timeout=20;"


Function GetConnection(ByVal strConnString As String) As ADODB.Connection

    Dim ret As ADODB.Connection

    Set ret = New ADODB.Connection
    ret.Open strConnString

    ' Return the connection object
    Set GetConnection = ret

End Function


Function GetCommand(ByRef oConn As ADODB.Connection, ByVal strCommand As String) As ADODB.Command

    Dim ret As ADODB.Command

    Set ret = New ADODB.Command

    With ret
        Set .ActiveConnection = oConn
        .CommandText = strCommand
        .CommandType = adCmdText
    End With

    ' Return the command
    Set GetCommand = ret

End Function

Function GetRecordSet(ByRef oCommand As ADODB.Command) As ADODB.Recordset
    Set GetRecordSet = oCommand.Execute
End Function


Public Sub fetchReport()

    Dim oCon As ADODB.Connection
    Dim oCom As ADODB.Command
    Dim oRecordSet As ADODB.Recordset
    Dim strCommand As String
    Dim hd As Integer

    ' Create and load the objects
    strCommand = "exec my_stored_procedure '" & Format(Range("dateFrom"), "yyyy-mm-dd") & "' ,'" & Format(Range("dateTo"), "yyyy-mm-dd") & "' "

    ' Connection string > Connection > Command > RecordSet
    Set oCon = GetConnection(strCONNECTION)
    Set oCom = GetCommand(oCon, strCommand)
    Set oRecordSet = GetRecordSet(oCom)


    If Not oRecordSet.EOF Then
        For hd = 0 To oRecordSet.Fields.Count - 1
            Worksheets("data").Cells(1, hd + 1).Value = oRecordSet.Fields(hd).Name      'insert column headers
        Next

        Sheets("data").Range("A2").CopyFromRecordset oRecordSet  'insert data
        Sheets("data").Range("A1").CurrentRegion.Name = "rsRange"  'set named range for pivot
    End If

    ActiveWorkbook.RefreshAll

End Sub

I hope this helps :)

Upvotes: 0

Drew
Drew

Reputation: 24960

I hope this is helpful. Been a long time since I have done this.

Schema

create table myTable
(   id int auto_increment primary key,
    dateColumn date not null,
    stuff varchar(100) not null
);
insert myTable(dateColumn,stuff) values
('2014-12-21','dogs'),('2015-02-21','frogs'),('2015-07-21','snakes'),('2015-12-21','cats');

Stored Proc

drop procedure if exists `my_stored_procedure`;
DELIMITER $$
CREATE PROCEDURE `my_stored_procedure`
(
    in fromDate date,
    in toDate date
)
BEGIN
    SELECT * 
    from myTable
    WHERE dateColumn >= fromDate AND dateColumn <= toDate; 
END
$$
DELIMITER ;

VBA

Function MySqlStoredProcRS(strSql As String) As ADODB.Recordset
    Dim conMySQL
    Set conMySQL = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    conMySQL.ConnectionString = ConnStr ' not shown but like yours in Op Question
    conMySQL.Open
    Set rs.ActiveConnection = conMySQL
    rs.CursorLocation = adUseClient
    rs.Open strSql, conMySQL, , , adCmdText
    Set MySqlStoredProcRS = rs
End Function
Public Sub fetchReport()

Dim rs As ADODB.Recordset
Dim sql As String
sql = "call my_stored_procedure ('" & Format(Range("dateFrom"), "yyyy-mm-dd") & "' ,'" & Format(Range("dateTo"), "yyyy-mm-dd") & "')"
Set rs = MySqlStoredProcRS(sql)
Dim hd As Integer


    If Not rs.EOF Then
            For hd = 0 To rs.Fields.Count - 1
                Worksheets("data").Cells(1, hd + 1).Value = rs.Fields(hd).Name  'insert column headers
            Next

        Sheets("data").Range("A2").CopyFromRecordset rs  'insert data
        Sheets("data").Range("A1").CurrentRegion.Name = "rsRange"  'set named range for pivot
    End If

ActiveWorkbook.RefreshAll

End Sub

Picture of Output (after clicked Blue thingie)

enter image description here

The Takeaway

I guess explore the changes to the new function MySqlStoredProcRS, the handling of the ADODB.RecordSet, using call, and parentheses wrapping the parameters in the call string.

Good luck.

Upvotes: 1

Related Questions