所以,数据库hotchpotch。
CALL myProcName;
,并且当我使用Set Result = CurrentDb.OpenRecordset("myProcName")
我想要实现的目标如下:
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。这让我因为很多原因而感到不寒而栗(其中包括安全性,可维护性和优雅性)。我坚信有一种更好的方法,希望按照我上面描述的方式。唯一的问题是:怎么做?
答案 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