通过VBA

时间:2016-11-27 11:50:20

标签: mysql vba ms-access stored-procedures parameter-passing

所以,数据库hotchpotch。

  • 我有一个MySQL数据库,它有存储过程。
  • 我有一个Access文档链接到MySQL数据库(我可以调查表格)作为前端(有表格和东西)
  • 我已经成功创建了一个ODBC Pass Through Query(我认为这就是所谓的)来从数据库调用其中一个存储过程。 Access中的查询实际上只是CALL myProcName;,并且当我使用Set Result = CurrentDb.OpenRecordset("myProcName")
  • 从VBA调用它时,我会得到我期望的结果

我想要实现的目标如下:

  • 在MySQL中有一个存储过程,它带有一个参数=>检查!
  • 让存储过程按预期工作=>签入phpMyAdmin =>检查!
  • 在Access中保存一个查询,该查询链接到此参数存储过程,其中包含固定参数值=>校验! (CALL myProcName('myParameterValue'),我可以像在进行无参数查询时那​​样从VBA调用它)
  • 每次执行查询时都可以指定'myParameterValue' => 不检查

我需要以某种方式在已保存查询的SQL定义中指定参数占位符,并在VBA中设置该参数。对于VBA部分,我有想法,我会发现相当优雅:

Private Sub ParametricQuery()
  Dim QDef As QueryDef
  Set QDef = CurrentDb.QueryDefs("myProcName")
  QDef.Parameters(*insert parameter name here*) = parameter value
  Dim Result As Recordset
  Set Result = QDef.OpenRecordset

  Do While Not Result.EOF
    MsgBox Result.Fields(1) 'Display a field from the results
  Loop
End Sub

但是我如何构建我的SQL定义?

PARAMETERS in_param TEXT;
CALL myProcName(in_param);

不起作用。如果我试试

Set QDef = CurrentDb.QueryDefs("myProcName")
MsgBox QDef.Parameters.Count

我收到一个Messagebox告诉我在我的查询定义中总共有0个参数,所以这不起作用。

我在网上找到的很多人都是通过字符串操作在VBA中构建实际的SQL。这让我因为很多原因而感到不寒而栗(其中包括安全性,可维护性和优雅性)。我坚信有一种更好的方法,希望按照我上面描述的方式。唯一的问题是:怎么做?

1 个答案:

答案 0 :(得分:2)

考虑使用ADO参数化查询来调用存储过程。目前,您正在使用DAO(访问'默认数据库API)来访问pass-thru查询(已保存的Access querydef)。但是,这种类型的查询在前端没有看到任何内容,只有后端RDMS,特别是MySQL SQL方言及其连接的数据库对象。因此,您无法将本地参数值绑定到它。 PARAMETERS子句只是Access SQL方言的一部分,并且将失败MySQL语法。

MySQL 存储过程

CREATE PROCEDURE `mystoredproc`(IN param VARCHAR(254))
BEGIN
   SELECT * FROM table WHERE field=param;
END

ADO 参数化查询

Public Sub CallMySQLProc()    
    Dim conn As Object, cmd As Object, rst As Object
    Const adCmdStoredProc = 4, adParamInput = 1, adVarChar = 200

    Set conn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")

    ' DSN-LESS CONNECTION
    conn.Open "Driver={MySQL ODBC 5.3 Unicode Driver};host=hostname;database=databasename;" _
                & "UID=username;PWD=****"

    ' CONFIGURE ADO COMMAND
    Set cmd = CreateObject("ADODB.Command")
    With cmd
        .ActiveConnection = conn
        .CommandText = "mystoredproc"
        .CommandType = adCmdStoredProc
        .CommandTimeout = 15
    End With

    ' APPEND NAMED PARAM
    cmd.Parameters.Append cmd.CreateParameter("param", adVarChar, _
                                              adParamInput, 254, "some.name@example.com")
    Set rst = cmd.Execute

    ' FREE RESOURCES
    rst.Close
    Set rst = Nothing
    Set cmd = Nothing
    Set conn = Nothing

End Sub

DAO 动态传递查询

在这里,您可以动态构建querydef的.SQL语句,但不会参数化:

Private Sub ParametricQuery()
  Dim QDef As QueryDef
  Dim Result As Recordset

  Set QDef = CurrentDb.QueryDefs("PassThruQ")
  QDef.SQL = "CALL mystoredproc('some.name@example.com')"

  Set Result = QDef.OpenRecordset

  Do While Not Result.EOF
    Debug.Print Result.Fields(1)    'Print to immediate window a field from the results
  Loop

  Result.close
  Set Result = Nothing
  Set QDef = Nothing
End Sub