使用SQLite ODBC在Excel中进行参数化查询

时间:2016-04-27 21:00:18

标签: excel vba sqlite odbc

我在Excel 2016中使用SQLite ODBC Driver v0.9993(win10)。使用外部源的主要动力是我有太多的数据可以让Excel得到理智的管理,因此它将根据用户选择的标准进行提取。因此,我想根据明确定义的工作表单元格的内容使用参数化查询。

我正在尝试两种方法:

  1. 直接VBA,我做这样的事情(粗略代码):

    Sub UpdateTables()
        Dim ws as Worksheet
        Dim adoCN As ADODB.Connection
        Dim adoCmd As ADODB.Command
        Dim adoRS As ADODB.Recordset
        Dim sDB as String
        Dim rCell as Range
        Set adoCN = New ADODB.Connection
        Set adoRS = New ADODB.Recordset
        ' ws is set to correct worksheet
        ' ...
        ' define sDB from worksheet cell
        With adoCN
            .Open "Provider=MSDASQL.1;Persist Security Info=True;" _
                & "Driver={SQLite3 ODBC Driver};" _
                & "Database=" & sDB & ";" _
                & "DSN=SQLite3 Datasource;LongNames=true;fksupport=true", "", "" '
        End With
        Set adoCmd = New ADODB.Command
        adoCmd.ActiveConnection = adoCN
        ' rCell points to cell containing query parameter
        Set adoParam = adoCmd.CreateParameter(, adVarChar, adParamInput, _
            Len(rCell.value), rCell.value)
        adoCmd.Parameters.Append adoParam
        adoCmd.CommandText = "SELECT * FROM TableName WHERE X = ?"
        adoRS.Open Source:=adoCmd, CursorType:=adOpenKeyset
        With ws.ListObjects(1).QueryTable
            Set .RecordSet = adoRS
            .Refresh ' errors with "Error 1004: invalid accessor flag"
        End With
    End Sub
    

    (代码已经简化,通常我包括健全性检查。)

  2. 基于GUI的Excel,新查询> 来自其他来源> 从ODBC ,将DSN设置为“SQLite3 Datasource”,并输入上面使用的连接字符串。

    不幸的是,“参数”按钮(连接> 选择查询> 属性> 定义 tab)显示为灰色。

  3. 我认为我更喜欢第二种解决方案,但现在都没有。

1 个答案:

答案 0 :(得分:0)

通过ADO连接而不是opening recordset,您需要从ADO command对象执行命令。这是一个经常讨论的 recordset .execute vs .open 主题。当然,请务必添加错误处理以捕获相关的错误/异常。

Sub UpdateTables()
On Error GoTo ErrHandle
    Dim ws as Worksheet
    Dim adoCN As New ADODB.Connection, adoRS As New ADODB.Recordset
    Dim adoCmd As New ADODB.Command    
    Dim sDB as String
    Dim rCell as Range

    'Set ws = ... '
    'sDB = ... '

    ' DATABASE CONNECTION '   
    adoCN.Open "Provider=MSDASQL.1;Persist Security Info=True;" _
                  & "Driver={SQLite3 ODBC Driver};" _
                  & "Database=" & sDB & ";" _
                  & "DSN=SQLite3 Datasource;LongNames=true;fksupport=true", "", "" 

    ' ADO COMMAND '
    With adoCmd
        .ActiveConnection = adoCN
        .CommandText = "SELECT * FROM TableName WHERE X = ?"
        .CommandType = adCmdText
        .Parameters.Append .CreateParameter(, adVarChar, adParamInput, _
                                            Len(rCell.value), rCell.value)
    End With

    ' EXECUTE RECORDSET '
    Set adoRS = adoCmd.Execute

    ' DEFINE QUERYTABLE '
    With ws.ListObjects(1).QueryTable
        Set .RecordSet = adoRS
        .Refresh
    End With

    ' CLOSE AND FREE RESOURCES '
    adoRS.Close: adoCN.Close
    Set adoRS = Nothing: Set adoCmd = Nothing: Set adoCN = Nothing    
    Exit Sub

ErrHandle:
    MsgBox Err.Number & " - " & Err.Description
    Set adoRS = Nothing: Set adCmd = Nothing: Set adCN = Nothing    
    Exit Sub    
End Sub