You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何OpenQuery在SQL函数外正常,函数内触发ADSDSOObject获取行错误?

问题原因及解决办法

为啥函数里会报错

SQL Server的标量值函数有严格的执行规则,你调用的ADSI链接服务器依赖ADSDSOObject这个OLE DB提供程序,刚好触发了两个限制:

  • 标量函数要求操作必须是确定性的——输入相同参数必须返回完全一致的结果,但访问AD目录的操作做不到(AD数据可能随时更新、网络状态也可能变化),不符合函数的执行要求。
  • 标量函数的运行环境限制了对外部资源的访问,ADSDSOObject这类调用外部系统的操作在该环境下无法正常获取结果集,因此抛出“无法获取行”的错误。

而直接执行的SELECT语句是在常规查询上下文,没有这些严格限制,所以能正常运行。

解决办法

换成表值函数

表值函数的限制比标量函数少,支持调用链接服务器的操作,代码修改如下:

CREATE FUNCTION [dbo].[cus_GetADLogin_TVF]
(   @displayName varchar(64) )
RETURNS TABLE
AS
RETURN
(
    SELECT sAMAccountName FROM 
        OpenQuery (ADSI, 'SELECT sAMAccountName, displayname FROM ''LDAP://mydomain.com'' WHERE objectCategory=''user''') AD
    WHERE AD.displayName = @displayName
)

调用方式:

SELECT sAMAccountName FROM dbo.cus_GetADLogin_TVF('Doug Kimzey')

改用存储过程

存储过程的运行环境完全支持访问外部资源,更适配这类场景,代码示例:

CREATE PROCEDURE [dbo].[cus_GetADLogin_SP]
    @displayName varchar(64),
    @sAMAccountName varchar(128) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    SELECT @sAMAccountName = sAMAccountName FROM 
        OpenQuery (ADSI, 'SELECT sAMAccountName, displayname FROM ''LDAP://mydomain.com'' WHERE objectCategory=''user''') AD
    WHERE AD.displayName = @displayName
END

调用方式:

DECLARE @result varchar(128)
EXEC dbo.cus_GetADLogin_SP 'Doug Kimzey', @result OUTPUT
SELECT @result AS sAMAccountName

内容的提问来源于stack exchange,提问作者Doug Kimzey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:57:18