从SQL Server 2008链接服务器中检索> 901行到Active Directory

如何解决从SQL Server 2008链接服务器中检索> 901行到Active Directory

|| 在SQL Server 2008(版本10.0.4000)中,我创建了到Active Directory服务器的链接服务器。 该查询:
select  TOP 901 *
from  openquery(adsisca,\'
select  givenName,sn,sAMAccountName          
from    \'\'LDAP://10.1.2.3:389\'\'
where   objectCategory = \'\'Person\'\'
        and
        objectClass = \'\'InetOrgPerson\'\'
\')
作品。 但是,更改查询并尝试检索902行不会:
select  TOP 902 *
    from  openquery(adsisca,\'
    select  givenName,sAMAccountName          
    from    \'\'LDAP://10.1.2.3:389\'\'
    where   objectCategory = \'\'Person\'\'
            and
            objectClass = \'\'InetOrgPerson\'\'
    \')
错误是:   Msg 7330,第16级,州2,第1行   无法从OLE DB获取行   提供程序\“ ADSDSOObject \”用于链接   服务器\“ adsisca \”。 我发现其他人在论坛上讨论相同的问题,但他们从未解决过,只是围绕它编写了多个视图并将它们合并在一起。 是否有更优雅的解决方案,是否可以更改某个地方以检索901行以上的设置?     

解决方法

使用联合来规避限制.. 像这样 :
select  TOP 901 *
from  openquery(adsisca,\'
select  givenName,sn,sAMAccountName          
from    \'\'LDAP://10.1.2.3:389\'\'
where   objectCategory = \'\'Person\'\'
        and
        objectClass = \'\'InetOrgPerson\'\'
        and
        sAMAccountName < \'\'m\'\'
\')
union
select  TOP 901 *
from  openquery(adsisca,sAMAccountName          
from    \'\'LDAP://10.1.2.3:389\'\'
where   objectCategory = \'\'Person\'\'
        and
        objectClass = \'\'InetOrgPerson\'\'
        and
        sAMAccountName >= \'\'m\'\'
\')
    ,我知道这是一个旧帖子,但是我也遇到了同样的问题,并检查了上面提出的解决方案。 (基本上是使用一堆较小的选择以及不断变化的条件来减少行数),我只是剪切了一个略有不同的版本,并将它们全部合并为Db视图。我不能为MaxPageSize事情烦恼-它看起来太费力了。
IF NOT EXISTS(SELECT 1 FROM sys.servers WHERE name = \'ADSI\') 
    EXEC sp_addlinkedserver \'ADSI\',\'Active Directory Services 2.5\',\'ADSDSOObject\',\'adsdatasource\'

-- Create a database view from unions of smaller selects. The max 901 records thing in AD forces us to do this.
DECLARE @queryFormat VARCHAR(MAX) = \'
SELECT * FROM OPENQUERY(ADSI,\'\'
    SELECT userPrincipalName,samAccountName,telephoneNumber,mail,middleName,givenName,displayName,distinguishedName
    FROM \'\'\'\'LDAP://OU=Users,OU=ABC,DC=XYZ,DC=local\'\'\'\'
    WHERE objectClass = \'\'\'\'User\'\'\'\' AND objectCategory = \'\'\'\'Person\'\'\'\' AND samAccountName = \'\'\'\'#p0\'\'\'\'\'\')\';

DECLARE @sql VARCHAR(MAX) = \'CREATE VIEW [AdView] AS \';
DECLARE @asciiValue INT = ASCII(\'A\');
DECLARE @asciiEnd INT = ASCII(\'Z\');
WHILE @asciiValue <= @asciiEnd BEGIN 
    SET @sql = @sql + replace(@queryFormat,\'#p0\',CHAR(@asciiValue) + \'*\');
    IF @asciiValue < @asciiEnd  SET @sql = @sql + \' UNION ALL \';
    SET @asciiValue = @asciiValue + 1;
END
--PRINT @sql;

-- the \'live\' view of the active directory data.
IF OBJECT_ID(\'[AdView]\') IS NOT NULL DROP VIEW [AdView]
EXEC(@sql);

-- a \'snapshot\' of the active directory data,for faster selects. you could execute this on a schedule to keep up to date.
IF OBJECT_ID(\'[AdTable]\',\'U\') IS NOT NULL DROP TABLE [AdTable]
SELECT * INTO [AdTable] FROM [AdView]
    ,问题        错误是:          消息7330,级别16,状态2,第1行无法从OLE DB提供程序“ ADSDSOObject”获取链接服务器“ adsisca”的行。         我发现其他人在论坛上讨论相同的问题,但是他们从未解决过,只是解决了问题,例如编写了多个视图并将它们合并在一起。      是否有更优雅的解决方案,是否可以更改某个地方以获取901>行以上的设置? 解决方案 我只是解决了我面临的相同问题,而无需进行任何Active Directory设置更改(并且我能够成功地从AD检索大约5万次登录,并且从AD域中获取一个登录帐户也不失踪): 您需要通过遍历属性的字符来解决ADSI查询限制。在此处查看解决方案:http://www.sqlservercentral.com/Forums/Topic231658-54-1.aspx#bm1249991 通过在仅ѭ5的地方写入
SELECT TOP 901 ...
解决了错误。 从2005年到2008年数据库迁移后,我遇到了这个问题,因为在SQL Server 2008中,限制为901行,而在SQL Server 2005中限制为1000行(不同之处是我们需要编写select TOP 901,而不是SQL Server 2005中必需的,否则程序将失败并显示错误)     ,我不太喜欢这里发布的其他选项的味道,因为对于大型域,很有可能拥有多个以相同的首字母开头的901个帐户-特别是如果您正在查看的计算机帐户,则可能会跟随一些使用相同的首字母的系统命名约定... 我进行了一些尝试,发现如果您通过uSNCreated订购openquery并在外部查询上放置TOP 901子句,它不会崩溃。 因此,这是我的SQL,它将所有活动目录对象(计算机,域控制器,用户和联系人)以901条记录的块的形式提取到临时表中,并为您提供了有关每个对象的一些有用信息。
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,userAccountControl,lastLogon,samaccountname,title,department,physicalDeliveryOfficeName,info,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,FamilyName,Location,Email,Phone,QuickDial,Mobile,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
    ,您需要在Active Directory中更改MaxPageSize设置。为此,您需要使用Ntdsutil.exe,您可以在run命令上键入它,然后按照以下步骤操作 在Ntdsutil.exe命令提示符下,键入7,然后按Enter。 在LDAP策略命令提示符下,键入
Set MaxPageSize to 2000
。 ->或您想要的任何数字 要查看更改,请键入
Show Values
要保存更改,请键入
Commit Changes
要退出,请输入
q
    ,我需要在Active Directory中更改MaxTempTableSize设置。为此,您需要使用Ntdsutil.exe,您可以在run命令上键入它,然后按照以下步骤操作
At the Ntdsutil.exe command prompt,type LDAP policies,and then press ENTER.
At the LDAP policy command prompt,type Set MaxTempTableSize to 2000. -> Or any number you want
To view the changes,type Show Values
To save the changes,typeCommit Changes
To quit,type q
    ,此版本的解决方案处理的情况是,以指定字符开头的用户数量仍大于901。它使用一个主过程调用另一个存储过程。
-- This procedure pulls a subset of LDAP users

CREATE PROC [dbo].[Select_LDAP_Rows]
(
    @MyChar CHAR(1)
)
AS
BEGIN

--DECLARE @MyChar CHAR(1) = \'A\';

DECLARE @queryFormat VARCHAR(MAX) = \'
    SELECT * FROM OPENQUERY(ADSI,\'\'
        SELECT displayName,facsimileTelephoneNumber
        FROM \'\'\'\'LDAP://OU=PHC,dc=MyCompany,dc=org\'\'\'\'
        WHERE objectClass = \'\'\'\'User\'\'\'\' AND objectCategory = \'\'\'\'Person\'\'\'\' AND displayName = \'\'\'\'\' + @MyChar + \'#p0\'\'\'\'\'\')
    \';

DECLARE @sql VARCHAR(MAX) = \'CREATE VIEW [AdView] AS \';
DECLARE @asciiValue INT = ASCII(\'A\');
DECLARE @asciiEnd INT = ASCII(\'Z\');

WHILE @asciiValue <= @asciiEnd BEGIN 
    SET @sql = @sql + replace(@queryFormat,CHAR(@asciiValue) + \'*\');
    IF @asciiValue < @asciiEnd  SET @sql = @sql + \' UNION ALL \';
    SET @asciiValue = @asciiValue + 1;
END

--PRINT @sql;

-- the \'live\' view of the active directory data.
IF OBJECT_ID(\'v_ADView\') IS NOT NULL DROP VIEW v_ADView

EXEC(@sql);

-- ADTable holds a \'snapshot\' of the active directory data.
IF OBJECT_ID(\'[Users_AD]\',\'U\') IS NULL
    SELECT DisplayName,TelephoneNumber AS Phone,Mail,FacsimileTelephoneNumber AS Fax 
    INTO [Users_AD] FROM v_ADView;
ELSE
    INSERT INTO [Users_AD] 
    SELECT DisplayName,FacsimileTelephoneNumber AS Fax 
    FROM v_ADView;

END


GO


-- By calling Select_LDAP_Rows with a separate character each time,-- build up a table containing all the LDAP data for each user.

ALTER PROC [dbo].[Select_LDAP_Rows_Master]
AS

BEGIN

-- ADTable holds a \'snapshot\' of the active directory data.
IF OBJECT_ID(\'[AdTable]\',\'U\') IS NOT NULL DROP TABLE [AdTable];

-- Create a database view from unions of smaller selects. The max 901 records thing in AD forces us to do this.

DECLARE @sql VARCHAR(200)
DECLARE @asciiValue INT = ASCII(\'A\');
DECLARE @asciiEnd INT = ASCII(\'Z\');

-- Create a view of the active directory data and insert to table Users_AD
WHILE @asciiValue <= @asciiEnd BEGIN 

    SET @sql = \'EXEC dbo.Select_LDAP_Rows \' + CHAR(@asciiValue) + \' \';
    SET @asciiValue = @asciiValue + 1;

    --PRINT @sql;

    EXEC(@sql);

END

END
    ,我喜欢union选项是最好和最简单的方法。 选择TOP 901 * 来自openquery(adsisca,\' 选择givenName,                 锡                 sAMAccountName 来自\'\'LDAP://10.1.2.3:389 \'\' 其中objectCategory = \'\'Person \'\'         和         objectClass = \'\'InetOrgPerson \'\'         和         sAMAccountName <\'\'m \'\' \') 联盟 选择TOP 901 * 来自openquery(adsisca,\' 选择givenName,                 锡                 sAMAccountName 来自\'\'LDAP://10.1.2.3:389 \'\' 其中objectCategory = \'\'Person \'\'         和         objectClass = \'\'InetOrgPerson \'\'         和         sAMAccountName> = \'\'m \'\' \')     ,我非常感谢John Sinclair的回答,我决定奉承最高的奉承形式-模仿。这是我对他的解决方案的解释。我没有选择OpenRowSet中的每个查询声明ADSI LDAP连接,而是选择了OpenQuery方法:
DECLARE @DomainFQDN VARCHAR(50) = \'<your.domain.FQDN>\';

IF OBJECT_ID(\'tempdb..#ADData\') IS NOT NULL
  DROP TABLE #ADData;

-- Query AD for all known user accounts
CREATE TABLE #ADData(
    lanId               NVARCHAR(256),firstName           NVARCHAR(256),lastName            NVARCHAR(256),email               NVARCHAR(256),costcenter          NVARCHAR(256),--Our AD implementation uses the optional extensionAttributes,defining 1 as cost center
    mobile              NVARCHAR(256),--In @Query below,the name of this column is the same as the LDAP returned parameter,so no equate is applied in the query
    country             NVARCHAR(256),usnCreated          BIGINT         --uSNCreated is an INT64 object type
);

--Define the AD LDAP connection
IF NOT EXISTS(SELECT 1 FROM sys.servers WHERE name = \'ADSI\') 
 EXEC master.dbo.sp_addlinkedserver
    @server = N\'ADSI\',@srvproduct = N\'Active Directory Services\',@provider = N\'ADsDSOObject\',@datasrc = @DomainFQDN;

DECLARE @Rowcount int;
DECLARE @LastCreatedFilter VARCHAR(200) = \'\';
DECLARE @ADrecordsToReturn smallint = 901;  --AD will not return more than 901 records per query (changed from 1000 at some point). You can set it to any value smaller to control the \'pagesize\' of returned results

--Loop mechanics:
-- - 1st loop: @Rowcount will be NULL but we need to looping to commence,thus ISNULL function
-- - Intermediate loops: Rowcount will equal the max number of requested records,indicating there may be more to query from AD
--SELECT @LastCreatedFilter = \'AND usnCreated = \'\'\'\'<yourvalue>\'\'\'\'\'; --Used during debugging to iniate the loop at a certain value
--DECLARE @TestStop int = 1;  -- @TestStop is a debug option to halt processing. It needs to be commented in or out at 3 places
WHILE ISNULL(@Rowcount,@ADrecordsToReturn) = @ADrecordsToReturn --AND @TestStop < 4  --Un-comment the three @TestStop lines to run a reduced sample query of AD,dictated by the value provided on this line (# of loops to process before stopping)
 BEGIN

    DECLARE @Query VARCHAR (2000) = 
     \'
        SELECT TOP \' + CONVERT(varchar(10),@ADrecordsToReturn) + \'
            lanId               = SamAccountName,firstName           = GivenName,lastName            = sn,email               = mail,bsbcc               = extensionAttribute1,country             = c,usnCreated
         FROM OpenQuery
          (
            ADSI,\'\'
                SELECT SamAccountName,extensionAttribute1,c,usnCreated
                 FROM \'\'\'\'LDAP://\' + @DomainFQDN + \'\'\'\'\'
                 WHERE objectCategory = \'\'\'\'Person\'\'\'\'
                 AND objectClass = \'\'\'\'user\'\'\'\'
                 \' + @LastCreatedFilter + \'
                 ORDER BY usnCreated
            \'\'
          )
     \';  
    INSERT INTO #ADData EXEC (@Query);
    SELECT @Rowcount = @@ROWCOUNT;
    SELECT @LastCreatedFilter = \'AND usnCreated > \' + LTRIM(STR((SELECT MAX(usnCreated) FROM #ADData)));
--PRINT @LastCreatedFilter;  --While debugging,used to determine progress
--SET @TestStop = @TestStop + 1;  -- @TestStop is a debug option to halt processing. It needs to be commented in or out at 3 places
 END;

EXEC master.dbo.sp_dropserver \'ADSI\';

--Do something with the results...
SELECT lanId,email,costcenter,country,usnCreated FROM #ADData order by lanId;
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-