在MS Access查询中调用SQL Server用户定义函数,获取“表达式中的未定义函数dbo.Funcname”

在MS access中(我认为它是365版,因为这是帮助主题所引用的,但是没有“帮助/关于”选项),由于业务逻辑的变化,我正在修改查询。该查询通过ODBC连接引用SQL Server(2016)服务器上的表。

在查询的“ SQL视图”中,我在“ WHERE”部分添加了一个子句:

AND(dbo_GetPrevNameCatAsOfDate(dbo_Name.ID,Date()='FM'))

将其保存正常(出现语法错误时access不会执行此操作。)

运行查询,将弹出一个消息对话框: 表达式中未定义的函数'dbo_GetPrevNameCatAsOfDate'。

我也在SQL视图中使用“ dbo”进行了尝试。并且在“获取”之前没有前缀,而不是“ dbo _”

该函数在SQL Server中运行时可以正常工作。 当我从SQL视图中删除该AND子句时,access查询工作正常。

您有什么想法吗?

谢谢!

CARBONARI001 回答:在MS Access查询中调用SQL Server用户定义函数,获取“表达式中的未定义函数dbo.Funcname”

如果要从Access运行SQL Server中定义的函数,则需要将查询设置为直通查询。使用通过查询按钮在设计视图中完成此操作。函数名称使用点dbo.GetPrevNameCatAsOfDate

此外,如果要使用SQL Server函数,则不能将它们与Access函数混合使用。这意味着Date()应该变成GETDATE()

否则,您必须在VBA中实现业务逻辑才能在本地运行它。但是通常,在T-SQL中实现它并在SQL Server上运行它会更快。

,

您没有提及dbo_GetPrevNameCatAsOfDate()函数驻留的位置/位置。

任何运行100%sql服务器端的东西(例如视图)都将要求您将VBA函数转换为T-SQL中我们所谓的“定标”函数。因此,您可以在T-SQL函数中重写上述VBA函数。创建此函数后,就像在Access SQL中一样,如何在任何SQL中使用自定义VBA函数,就可以在T-SQL中进行相同的操作。

在大多数情况下,您在Access SQL中使用的自定义VBA函数可能是一个相当短的函数,因此将此类函数转换为T-sql函数(它们称为缩放器函数)将导致相同的开发过程。

唯一的缺点是,虽然您可以在t-sql中使用完全相同的函数名称,但不幸的是,所有定标器函数都需要schemea前缀(我真希望不是这种情况)。因此,如果要将客户端Access SQL剪切并粘贴到SSMS中并创建视图?好了,您必须添加一个dbo。在函数名称前面。但是总而言之,对于此类迁移项目,重新创建VBA功能作为T-SQL是一个好主意。我在VBA中有一个自定义的GST()函数。并将sql和部件移到SQL,然后我在T-SQL中重新创建了GST()函数,因此我能够在我的t-sql查询和视图中继续使用GST()函数。

最后但并非最不重要?

好吧,毫无疑问,在访问客户端,您将链接到该视图。因此,在链接视图上创建一个客户端查询,然后可以包含您的自定义VBA函数。

如果您确实需要并且想要使用链接视图,而不是使用基于链接视图的客户端查询,则可以简单地将自定义VBA函数重新创建为t-sql缩放器函数,然后继续使用该功能可在任何t-sql查询(包括视图)中使用。

因此,链接视图上的客户端查询可以包括+使用您的函数。但是,为了易于使用和获得最佳性能,请考虑将VBA函数例程创建为t-sql例程。尽管与VBA相比,t-sql受到一些限制,但它具有循环,字符串表达式,查询功能,并且实际上具有与典型VBA例程中非常相似的功能集-尤其是在sql查询中使用的功能作为一种表达。

编辑

你有这个:

AND (dbo_GetPrevNameCatAsOfDate( dbo_Name.ID,Date() = 'FM') )

看起来不太正确。假定此函数返回一些字符串,并且您具有:

dbo_GetPrevNameCatAsOfDate( dbo_Name.ID,Date()

应该是:

dbo_GetPrevNameCatAsOfDate( dbo_Name.ID,Date() )

并不真正在乎您在什么地方,何时何地使用此功能,但是您需要为该功能加上一个括号。如前所述,您还必须在架构上为ANY scaler函数添加前缀。因此,我们得到:

dbo.dbo_GetPrevNameCatAsOfDate( dbo_Name.ID,Date() )

但是,SQL Server中没有date()函数。您必须使用GETDATE()

但是如何!! GETDATE()将在今天返回,时间部分也会返回。

那么,如果您只想要今天,只想要一个日期,而不想要一个日期时间?

然后您必须使用此:

 CAST (GETDATE() AS DATE) 

所以现在我们有了这个法律表达:

dbo.dbo_GetPrevNameCatAsOfDate( dbo_Name.ID,CAST (GETDATE() AS DATE) )

然后使用上面的代码,假定该函数返回varChar,因此我们现在可以将上面的代码交换到您的where子句中,然后得到:

AND 
(
dbo.dbo_GetPrevNameCatAsOfDate( dbo_Name.ID,CAST (GETDATE() AS DATE) ) = 'FM'
)

因此没有DATE()t-sql。而且您必须以dbo为前缀。

本文链接:https://www.f2er.com/3164715.html

大家都在问