如何从具有命名参数的表值函数创建ADODB记录集

时间:2010-07-26 22:50:04

标签: sql-server vba ado user-defined-functions

这有效:

Dim rst As New ADODB.Recordset
rst.Open "SELECT * FROM dbo.ftblTest(1,2,3)", CP.Connection, adOpenKeyset, adLockReadOnly

但这样做会更好:

rst.Open "SELECT * FROM dbo.ftblTest(@Param1=1,@Param2=2,@Param3=3)", CP.Connection, adOpenKeyset, adLockReadOnly

如果我尝试第二种方法,我会收到错误:“没有为ftblTest函数提供参数”

是否可以将命名参数与多语句表值函数一起使用?

编辑1:使用命令对象添加的示例

首先是SQL

create function ftblTest (@Input int)
RETURNS @Results TABLE (
  OutputField int
  )
AS
BEGIN
INSERT INTO @Results SELECT @Input
Return
End

部分代码(从Access 2003 ADP内部运行,并连接到正确的SQL DB)

Public Sub test()
  Dim rst As New ADODB.Recordset
  Dim cmd As New ADODB.Command

  'method 1 works
  rst.Open "SELECT * FROM dbo.ftblTest(2)", CurrentProject.Connection, adOpenKeyset, adLockReadOnly
  Debug.Print rst.Fields(0)
  rst.Close

  With cmd
    .ActiveConnection = CurrentProject.Connection
    .CommandType = adCmdTable

    'method 2 works
    .CommandText = "dbo.ftblTest(3)"
    Set rst = cmd.Execute
    Debug.Print rst.Fields(0)

    'method 3 fails
    .CreateParameter "@Input", adInteger, adParamInput, , 4
    .CommandText = "dbo.ftblTest(@Input)"
    Set rst = cmd.Execute 'error here:-2147217900   Must declare the scalar variable "@Input".
    Debug.Print rst.Fields(0)

  End With
End Sub

如何让命名参数在方法3中起作用?

编辑2:修改测试代码以使用Parameters.Append

Public Sub test()
  Dim rst As New ADODB.Recordset
  Dim cmd As New ADODB.Command
  Dim p As New ADODB.Parameter

  With cmd
    .ActiveConnection = CurrentProject.Connection
    .CommandType = adCmdTable

    'Parameter Append method fails
    p = .CreateParameter("@Input", adInteger, adParamInput, , 4)
    Debug.Print p.Name, p.Type = adInteger, p.Direction = adParamInput, p.SIZE, p.Value 'note that name not set!
    With p
      .Name = "@Input"
      .Type = adInteger
      .Direction = adParamInput
      .SIZE = 4 'this shouldn't be needed
      .Value = 4
    End With
    Debug.Print p.Name, p.Type = adInteger, p.Direction = adParamInput, p.SIZE, p.Value 'properties now set
    .Parameters.Append p
    .CommandText = "dbo.ftblTest(@Input)"
    Set rst = cmd.Execute 'error here:-2147217900   Must declare the scalar variable "@Input".
    Debug.Print rst.Fields(0)

  End With
End Sub

这仍然不起作用。

编辑3:我从创建参数

中删除了@

按照建议并尝试了CommandText 3种方法并获得了3种不同的错误:

.CommandText = "dbo.ftblTest" 

错误:未为函数“dbo.ftblTest”提供参数。

.CommandText = "dbo.ftblTest()" 

错误:为过程或函数dbo.ftblTest提供的参数数量不足。

.CommandText = "dbo.ftblTest(Input)" 

错误:“输入”不是可识别的表提示选项。如果要将其作为表值函数或CHANGETABLE函数的参数,请确保将数据库兼容性模式设置为90.

3 个答案:

答案 0 :(得分:0)

是的,您可以使用带有表函数的参数。

rst.Open "SELECT * FROM dbo.ftblTest(@Param1,@Param2,@Param3)", CP.Connection, adOpenKeyset, adLockReadOnly

在打开数据库连接之前,添加参数并设置它们的值。

答案 1 :(得分:0)

不要在参数名称中使用@,也不要在命令文本中按名称列出参数。我总是使用存储过程完成此操作,因此我不确定命令文本的处理方式究竟如何处理。

尝试:

.CreateParameter“Input”,adInteger,adParamInput ,, 4

.CommandText =“dbo.ftblTest()”

或者:

.CommandText =“dbo.ftblTest”

答案 2 :(得分:0)

这应该有效:

将cmd用作新的ADODB.Command

使用cmd

.ActiveConnection = CurrentProject.Connection
.CommandType = adCmdTable
'you need to add question a mark for each parameter
.CommandText = "dbo.ftblTest(?)"
'you can even add a order by expression like:
.CommandText = "dbo.ftblTest(?) ORDER BY ..."
.Parameters.Append .CreateParameter("@Input", adInteger, adParamInput, , 4)

Set rst = cmd.Execute 
Debug.Print rst.Fields(0)

结尾为