Sql 错误:无法从OLE DB提供程序中获取行";ADsDSOObject“;“用于链接服务器”;ADSI“;

Sql 错误:无法从OLE DB提供程序中获取行";ADsDSOObject“;“用于链接服务器”;ADSI“;,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,当我尝试为用户查询广告时,我收到以下错误: 无法从链接服务器“ADSI”的OLE DB提供程序“ADsDSOObject”中获取行 我假设问题是由于1000行限制(或SQLServer2008中的901行)。我可以分页查询,但我正在寻找一种解决方法,允许我一次检索1000多个 如果有帮助,我将使用SQLServer2008R2。 这是我的问题 SELECT samaccountname AS Account, ISNULL(givenName, '''') AS givenName, ISNU

当我尝试为用户查询广告时,我收到以下错误:

无法从链接服务器“ADSI”的OLE DB提供程序“ADsDSOObject”中获取行

我假设问题是由于1000行限制(或SQLServer2008中的901行)。我可以分页查询,但我正在寻找一种解决方法,允许我一次检索1000多个

如果有帮助,我将使用SQLServer2008R2。 这是我的问题

SELECT  samaccountname AS Account, ISNULL(givenName, '''') AS givenName, ISNULL(SN, '''') AS SN, ISNULL(DisplayName, '''') as DisplayName, ISNULL(Title, '''') AS Title 
                        FROM OpenQuery(ADSI, 
                        'SELECT SamAccountName, givenName, SN, DisplayName, Title
                        FROM ''LDAP://corpdomain.corp'' 
                        WHERE objectClass = ''User'' and (SN = ''*'' or givenName = ''*'')')
有什么想法吗

编辑-
经过进一步检查,我意识到我也无法正确地分页此查询。有没有人有什么建议可以让我对结果进行分页,或者有什么解决方法可以让我返回901个以上的结果?

从您对我的评论的回复来看,似乎SQL代理作业启动SSIS包是一种理想的方法。以下是如何在SSIS中访问Active Directory:

  • 创建新的SSIS项目
  • 将数据流任务添加到控制流
  • 单击数据流选项卡
  • 将ADO NET源从工具箱拖动到数据流
  • 双击ADO NET源代码
  • 单击OLE DB连接管理器旁边的“新建”按钮
  • 单击“配置ADO.NET连接管理器”中的“新建”按钮 对话
  • 单击“提供程序”下拉列表上的向下箭头
  • 在列表中找到OleDb的.Net提供程序,然后双击它
  • 在列表中查找Microsoft目录服务的OLE DB提供程序 然后双击它
  • 单击OK按钮
  • 在服务器或文件名中放入ActiveDirectory
  • 突出显示数据连接中的ActiveDirectory
  • 单击OK按钮
  • 将数据访问模式更改为SQL命令
  • 在SQL命令文本框中,输入
    ;(&(objectClass=User)(objectCategory=Person));识别名、显示名、序列号、给定名、中间名、邮件、电话号码;子树
  • 将域和tld更改为适用于您的 域并添加任何其他适当的LDAP路径元素
  • 向查询中添加任何其他适当的ActiveDirectory属性
  • 单击OK按钮
  • 您将看到错误消息,指示数据类型 不支持“System.Object”。这些都可以忽略
  • 单击“警告”对话框上的“确定”按钮
  • 右键单击ADO NET源代码
  • 单击属性
  • 将ValidateExternalMetadata更改为False
  • 您可能还希望执行以下步骤,但请注意,如果执行此操作并且Active Directory属性长度超过4000个字符,则它将在数据流中被截断

  • 右键单击ADO NET源代码
  • 单击“显示高级编辑器”
  • 转到“输入和输出属性”选项卡
  • 展开ADO NET源代码输出
  • 展开输出列
  • 对于每个列,将数据类型更改为Unicode字符串[DT_WSTR]并 将长度设置为4000
  • 单击OK按钮
  • 双击ADO网络源代码转到错误输出
  • 为Trunctation下的行选择所有值
  • 列表项
  • 在“将此值设置为选定单元格”下,选择“忽略失败”
  • 单击应用按钮
  • 单击OK按钮
  • 请注意,还支持此查询格式:

    SELECT     distinguishedName, displayName, sn, givenName, middleName, mail, telephoneNumber
    FROM         'LDAP://DC=domain,DC=tld'
    WHERE     objectClass = 'User' AND objectCategory = 'Person'
    
    有关提供程序支持的查询格式的更多信息,请参阅MSDN文章。

    问题 当我尝试为用户查询广告时,我收到以下错误:

    无法从链接服务器“ADSI”的OLE DB提供程序“ADsDSOObject”中获取行

    我假设问题是由于1000行限制(或SQLServer2008中的901行)。我可以分页查询>,但我正在寻找一种解决方法,允许我一次检索1000多个

    如果有帮助,我将使用SQLServer2008R2。这是我的问题 >

    有什么想法吗

    编辑-进一步检查后,我意识到我也无法正确地分页此查询。>有没有人提供一些建议,让我可以翻页搜索结果,或者提供一个解决方案,让我可以返回901个以上的结果

    我的解决方法 我刚刚解决了我面临的同样问题,通过优化应用分页(我能够成功地从广告中检索到大约50k个登录,并且从广告域中获取单个登录帐户也不丢失):

    您需要通过循环遍历属性的字符来绕过ADSI查询限制。请参见此处的解决方案:

    通过写入
    selecttop901…
    而不是
    SELECT
    来解决该错误


    是的,这个问题与使用SQLServer2008R2有关。在将数据库从2005年迁移到2008年后,我遇到了这个问题,因为在SQL Server 2008中,有901行的限制,而SQL Server 2005中的限制是1000行(区别在于我们需要编写select TOP 901,这在SQL Server 2005中不是必需的,否则程序会出错)

    我用Magnus Reuter的另一篇帖子解决了这个问题——我以为我给了你们所有人一个链接,因为它很简单,也很巧妙

    他做了两个查询,通过使用UNION连接它们,但对于第一个查询,他选择了all sAMAccountname m。当然,如果你发现你的中间不是字母“m”,你可以相应地调整它,但一般来说,如果你有1000-2000条记录,它将是“m”


    我也遇到了这个问题,不喜欢按帐户名的第一个字母分页的常见解决方案。这将意味着26个单独的AD调用,并且仍然可能失败,因为在一个大型域中,很可能有超过901个帐户以相同的第一个字母开头-特别是如果您正在查看计算机帐户,这些帐户可能遵循一些使用相同的第一个字母的系统命名约定

    我在附近玩了一会儿
    SELECT  samaccountname AS Account, ISNULL(givenName, '''') AS givenName, ISNULL(SN, '''') AS SN, ISNULL(DisplayName, '''') as DisplayName, ISNULL(Title, '''') AS Title 
                        FROM OpenQuery(ADSI, 
                        'SELECT SamAccountName, givenName, SN, DisplayName, Title
                        FROM ''LDAP://corpdomain.corp'' 
                        WHERE objectClass = ''User'' and (SN = ''*'' or givenName = ''*''
    
    CREATE TABLE #ADData(
        Login           NVARCHAR(256)
        ,CommonName     NVARCHAR(256)
        ,GivenName      NVARCHAR(256)
        ,FamilyName     NVARCHAR(256)   
        ,DisplayName    NVARCHAR(256)
        ,Title          NVARCHAR(256)
        ,Department     NVARCHAR(256)
        ,Location       NVARCHAR(256)
        ,Info           NVARCHAR(256)
        ,LastLogin      BIGINT
        ,flags          INT
        ,Email          NVARCHAR(256)
        ,Phone          NVARCHAR(256)   
        ,Mobile         NVARCHAR(256)
        ,Quickdial      NVARCHAR(256)
        , usnCreated    INT
    )
    
    DECLARE @Query      VARCHAR (2000)
    DECLARE @Filter     VARCHAR(200)
    DECLARE @Rowcount   INT
    
    select @Filter =''
    
    WHILE ISNULL(@rowcount,901)  = 901 BEGIN
    
        SELECT @Query = '
        SELECT top 901
                Login           = SamAccountName
                , CommonName    = cn
                , GivenName
                , FamilyName    = sn    
                , DisplayName
                , Title
                , Department
                , Location      = physicalDeliveryOfficeName
                , Info
                , LastLogin     = CAST(LastLogon AS bigint)
                , flags         = CAST (UserAccountControl as int)
                , Email         = mail
                , Phone         = telephoneNumber
                , Mobile        = mobile
                , QuickDial     = Pager
                , usnCreated
            FROM OPENROWSET(''ADSDSOObject'', '''', ''
                    SELECT cn, givenName, sn, userAccountControl, lastLogon, displayName, samaccountname, 
                    title,  department, physicalDeliveryOfficeName, info, mail, telephoneNumber, mobile, pager, usncreated
                FROM ''''LDAP://[ldap-query-string]'''' 
                WHERE objectClass=''''Person''''
                AND objectClass = ''''User''''
                ' + @filter + '
                ORDER BY usnCreated'')'             
        INSERT INTO #ADData EXEC (@Query) 
        SELECT @Rowcount = @@ROWCOUNT
        SELECT @Filter = 'and usnCreated > '+ LTRIM(STR((SELECT MAX(usnCreated) FROM #ADData)))
    
    END
    
    SELECT LOGIN            
            , CommonName    
            , GivenName
            , FamilyName
            , DisplayName
            , Title         
            , Department
            , Location      
            , Email         
            , Phone         
            , QuickDial     
            , Mobile        
            , Info          
            , Disabled      = CASE WHEN CAST (flags AS INT) & 2 > 0 THEN 'Y' ELSE NULL END 
            , Locked        = CASE WHEN CAST (flags AS INT) & 16  > 0 THEN 'Y' ELSE NULL END 
            , NoPwdExpiry   = CASE WHEN CAST (flags AS INT) & 65536  > 0 THEN 'Y' ELSE NULL END 
            , LastLogin     = CASE WHEN ISNULL(CAST (LastLogin AS BIGINT),0) = 0 THEN NULL ELSE 
                                DATEADD(ms, (CAST (LastLogin AS BIGINT) / CAST(10000 AS BIGINT)) % 86400000,
                                DATEADD(day, CAST (LastLogin AS BIGINT) / CAST(864000000000 AS BIGINT) - 109207, 0)) END 
            , Type = CASE WHEN flags  & 512 = 512 THEN 'user' 
                        WHEN flags IS NULL THEN 'contact' 
                        WHEN flags & 4096 = 4096 THEN 'computer'
                        WHEN flags & 532480 = 532480 THEN 'computer (DC)' END
    FROM #ADData
    ORDER BY Login
    
    DROP TABLE #ADData