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

Posted

技术标签:

【中文标题】如何从具有命名参数的表值函数创建 ADODB 记录集【英文标题】:How to create an ADODB Recordset From a Table Valued Function with Named Parameters 【发布时间】:2010-07-26 22:50:04 【问题描述】:

这行得通:

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。

【问题讨论】:

可能感兴趣:w3schools.com/ado/met_comm_createparameter.asp 【参考方案1】:

是的,您可以将参数与表函数一起使用。

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

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

【讨论】:

不确定我应该怎么做。我将在我的问题中添加示例。 查看@Remou 添加的链接。这似乎显示了如何添加参数的语法。 查看了一下并添加了 Parameters.Append 位,但它仍然不起作用。请参阅上面的新示例代码。 在这一点上,我们有一点盲人在这里引导盲人。我会看看我是否不能抓住一个对编码有一点了解的人。您使用什么语言? 谢谢先生。我使用的是 MS Access 2003 ADP,所以语言是 VBA,数据访问是 ADODB2.5,数据库是 MS SQL Server 2008 数据库。请参阅关于罗伯特答案的新评论。我开始怀疑是否不可能在 Ta 值函数上使用命名参数。【参考方案2】:

不要在参数名称中使用@,也不要在命令文本中按名称列出参数。我一直使用存储过程来完成此操作,所以我不确定括号是如何处理命令文本的。

尝试:

.CreateParameter "Input", adInteger, adParamInput, , 4

还有:

.CommandText = "dbo.ftblTest()"

或者:

.CommandText = "dbo.ftblTest"

【讨论】:

我从 create 参数中删除了 @,尝试了 3 种 CommandText 方法并得到了 3 个不同的错误: .CommandText = "dbo.ftblTest" 错误:未为函数 'dbo.ftblTest' 提供参数。 .CommandText = "dbo.ftblTest()" 错误:为过程或函数 dbo.ftblTest 提供的参数数量不足。 .CommandText = "dbo.ftblTest(Input)" 错误:“输入”不是可识别的表提示选项。如果它打算作为表值函数或 CHANGETABLE 函数的参数,请确保您的数据库兼容模式设置为 90。【参考方案3】:

这应该可行:

Dim cmd As New ADODB.Command

With 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)

End With

【讨论】:

以上是关于如何从具有命名参数的表值函数创建 ADODB 记录集的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 sqlkata 中查询参数化的表值函数?

表值参数

sqlserver中的表值函数和标量值函数

sql server表值函数和视图如何一起使用

如何在实体框架代码优先方法中使用表值函数?

sql中的表值函数与标量值函数区别与用法