2016-11-27 178 views
1

因此,数据库hotchpotch。通过VBA在Access前端执行MySQL存储过程

  • 我有一个存储过程的MySQL数据库。
  • 我有一个连接到MySQL数据库(我可以调查表)的Access文件作为前端(与形式和东西)
  • 我已经成功创建了一个ODBC通过查询(我认为这就是他们是什么调用)从数据库调用其中一个存储过程。在访问查询实际上只是CALL myProcName;,给我我希望当我Set Result = CurrentDb.OpenRecordset("myProcName")

把它从VBA的结果是什么,我想实现如下:

  • 已经在存储过程需要一个参数的MySQL =>检查!
  • 让该存储过程按预期工作=>在phpMyAdmin中检查=>检查!
  • 在Access中保存了一个查询,该查询链接到此参数存储过程并给定固定参数值=>检查! (CALL myProcName('myParameterValue'),我可以调用从VBA,就像我做的unparametric查询)
  • 必须指定'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 

我得到一个消息框,告诉我有一个总的在我的查询定义0参数是,这样是行不通的。

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

+0

你能后的'在MySQL中建立PROCEDURE'线(无需整个PROC)?命名的参数及其类型非常重要。 – Parfait

+0

嗯,我通过myphpadmin中相当不错的“创建过程”界面创建了程序。它有一个参数方向“IN”(很明显),类型为VARCHAR,长度为254(电子邮件地址的最大长度)。并且该过程做了一个简单的'SELECT * FROM table WHERE field = param' – lhiapgpeonk

回答

2

考虑使用ADO作为参数化查询来调用存储过程。目前,您正在使用DAO(Access的默认数据库API)来访问传递查询(保存的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, "[email protected]") 
    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('[email protected]')" 

    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 
+0

行,所以它不能轻易完成:)。有没有办法避免在代码中给连接字符串? Acces知道如何连接到数据库,它可以显示表格。那么,为什么我需要重新指定密码并且明显地为所有人?动态构建SQL有多安全?我看到了一大堆SQL注入的潜力,我试图避免。 (希望)做好事情和事情。但迄今为止感谢! – lhiapgpeonk

+1

只需使用文件[DSN](https://support.microsoft.com/en-us/kb/966849),代码中不会显示任何凭据。您可以在ODBC传递或外部工具/ ODBC或obdcad32.exe的相同对话框中为您的MySQL数据库构建一个(存储的文本文件)。仅供参考 - ADO可能是VBA运行参数化查询的唯一方法! – Parfait

+0

只需阅读DSN上的文章:我已经在窗口的控制面板中将我的数据库指定为ODBC数据源,这就是Access知道如何连接到数据库的位置,因此应该是系统DSN。任何机会,我可以在VBA中使用它?信息是没有问题的... – lhiapgpeonk