SQL Clone
SQLServerCentral is supported by Redgate
 
Log in  ::  Register  ::  Not logged in
 
 
 


SQL ADSI Query limitation


SQL ADSI Query limitation

Author
Message
Jan-155192
Jan-155192
SSC Veteran
SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)

Group: General Forum Members
Points: 293 Visits: 1

Hi,

I am trying to query a list of 2500 users out of the AD in SQL Server with the following query:

SELECT employeeId, SAMAccountName, Mail
FROM OPENQUERY( ADSI, 'SELECT Mail, SAMAccountName, employeeID FROM 'LDAP://dc=central,dc=mydomain,dc=int''WHERE objectCategory = ''Person''' )

However the result set seems to be limited to 1000 records. I have read that the "Page Size" parameter for AD should be given, but I don't know the exact SQL syntax.

... 'LDAP://dc=central,dc=mydomain,dc=int''WHERE objectCategory = ''Person'';''Page Size''=50' ) doesn't work. Neither does the range parameter.

Somebody suggested that I should partition the query, asking first for all userids starting with A, then B,... but I don't like that suggestion too much and even if I would use it, the Like 'A%' doesn't work.

Does somebody have any experience with this?

Many thanks,

Jan


vinny_1973
vinny_1973
SSC Veteran
SSC Veteran (212 reputation)SSC Veteran (212 reputation)SSC Veteran (212 reputation)SSC Veteran (212 reputation)SSC Veteran (212 reputation)SSC Veteran (212 reputation)SSC Veteran (212 reputation)SSC Veteran (212 reputation)

Group: General Forum Members
Points: 212 Visits: 86

Have a search on the site, as someone else asked the same question a week or so ago. Basically though, my understanding from the answers to that article was that the limit of 1000 records is set (hardcoded!) in AD and there is nothing you can do to change it ... therefore, paging your results was the only way to accomplish what you want!





Don Staten
Don Staten
SSC Journeyman
SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)

Group: General Forum Members
Points: 89 Visits: 50

Vinny is right. ADSI is limited to returning the first 1000 records without paging. Here's a Microsoft article for reference:

http://msdn.microsoft.com/library/en-us/adsi/adsi/paging_with_idirectorysearch.asp?frame=true

Quote from article:

"Searches of the Active Directory performed without paging are limited to returning a maximum of the first 1000 records, so you must use a paged search if there is the possibility that the result set will contain more than 1000 items."


Jan-155192
Jan-155192
SSC Veteran
SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)

Group: General Forum Members
Points: 293 Visits: 1

Vinny & Newbie,

Thanks, but I knew this. My question is: how can we do this paging from the OPENQUERY function?

In a vb script (or for that matter any language that uses ADO), we can write something like that:

objCommand.CommandText = _
"<LDAP://dc=Central,dc=mydomain,dc=int>;(objectCategory=user)" & _
";distinguishedName,Name,sAMAccountName,primaryGroupID,memberOf,canonicalName,Mail,telephoneNumber;subtree"
objCommand.Properties("Page Size") = 50

This tells AD to send batches with 50 records at one time. But where can I put this parameter in the SQL syntax? The following doesn't work:

SELECT employeeId, SAMAccountName, Mail
FROM OPENQUERY( ADSI, 'SELECT Mail, SAMAccountName, employeeID FROM 'LDAP://dc=central,dc=mydomain,dc=int''WHERE objectCategory = ''Person'';''Page Size''=50' )

I can partition (not page!) the query like this:

... FROM OPENQUERY( ADSI, 'SELECT Mail, SAMAccountName, employeeID FROM ''LDAP://dc=central,dc=mydomain,dc=int''WHERE objectCategory = ''Person'' AND SAMAccountName = ''A*''' )

and ask for A,B,C, ... , Z. But I prefer the paging attribute, and would like to know how to submit it.

Many thanks,

Jan


Jan-155192
Jan-155192
SSC Veteran
SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)SSC Veteran (293 reputation)

Group: General Forum Members
Points: 293 Visits: 1

By the way, I ended up with the following code. Thanks for helping.

Jan


CREATE TABLE #tmpADUsers
( employeeId varchar(10) NULL,
SAMAccountName varchar(255) NOT NULL,
email varchar(255) NULL)
GO

/* AD is limited to send 1000 records in one batch. In an ADO interface you can define this batch size, not in OPENQUERY.
Because of this limitation, we just loop through the alphabet.
*/

DECLARE @cmdstr varchar(255)
DECLARE @nAsciiValue smallint
DECLARE @sChar char(1)

SELECT @nAsciiValue = 65

WHILE @nAsciiValue < 91
BEGIN

SELECT @sChar= CHAR(@nAsciiValue)

EXEC master..xp_sprintf @cmdstr OUTPUT, 'SELECT employeeId, SAMAccountName, Mail FROM OPENQUERY( ADSI, ''SELECT Mail, SAMAccountName, employeeID FROM ''''LDAP://dc=central,dc=mydomain,dc=int''''WHERE objectCategory = ''''Person'''' AND SAMAccountName = ''''%s*'''''' )', @sChar

INSERT #tmpADUsers
EXEC( @cmdstr )

SELECT @nAsciiValue = @nAsciiValue + 1
END

DROP TABLE #tmpADUsers


Don Staten
Don Staten
SSC Journeyman
SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)SSC Journeyman (89 reputation)

Group: General Forum Members
Points: 89 Visits: 50

Jan - I misunderstood your original question. Kudos on the work-around and thank you for posting it on the forum.

I did, however,find a Microsoft article (Article 299410) that specifically addresses the paging issue within a distributed query. You must use other means to retrieve more than 1000 objects from ADSI. Quote:

"While paging is available through ADSI's OLEDB provider, there is currently no way available to perform it from a SQL distributed query. This means that the total number of objects that can be returned for a query is the server limit. In the Windows 2000 Active Directory, the default server limit is 1,000 objects."

http://support.microsoft.com/default.aspx?scid=kb;en-us;299410

Don


jonathan.stokes
jonathan.stokes
Grasshopper
Grasshopper (18 reputation)Grasshopper (18 reputation)Grasshopper (18 reputation)Grasshopper (18 reputation)Grasshopper (18 reputation)Grasshopper (18 reputation)Grasshopper (18 reputation)Grasshopper (18 reputation)

Group: General Forum Members
Points: 18 Visits: 77
SSC-Enthusiastic

You are the best. I have been trying to come up with something to overcome the 1000 limit on and off for the last few weeks.

Brilliant solution and thanks to you.
YSLGuru
YSLGuru
SSCommitted
SSCommitted (1.8K reputation)SSCommitted (1.8K reputation)SSCommitted (1.8K reputation)SSCommitted (1.8K reputation)SSCommitted (1.8K reputation)SSCommitted (1.8K reputation)SSCommitted (1.8K reputation)SSCommitted (1.8K reputation)

Group: General Forum Members
Points: 1834 Visits: 1665
Jan-155192 (10/25/2005)


By the way, I ended up with the following code. Thanks for helping.

Jan


CREATE TABLE #tmpADUsers
( employeeIdvarchar(10) NULL,
SAMAccountNamevarchar(255) NOT NULL,
emailvarchar(255) NULL)
GO

/* AD is limited to send 1000 records in one batch. In an ADO interface you can define this batch size, not in OPENQUERY.
Because of this limitation, we just loop through the alphabet.
*/

DECLARE @cmdstr varchar(255)
DECLARE @nAsciiValue smallint
DECLARE @sChar char(1)

SELECT @nAsciiValue = 65

WHILE @nAsciiValue < 91
BEGIN

SELECT @sChar= CHAR(@nAsciiValue)

EXEC master..xp_sprintf @cmdstr OUTPUT, 'SELECT employeeId, SAMAccountName, Mail FROM OPENQUERY( ADSI, ''SELECT Mail, SAMAccountName, employeeID FROM ''''LDAP://dc=central,dc=mydomain,dc=int''''WHERE objectCategory = ''''Person'''' AND SAMAccountName = ''''%s*'''''' )', @sChar

INSERT #tmpADUsers
EXEC( @cmdstr )

SELECT @nAsciiValue = @nAsciiValue + 1
END

DROP TABLE #tmpADUsers


I know this reply is over a year later but I came across your post while searching on the ADSI Linked server provider. I can get your sample to work but I hit a brick wall when I try to get too many columns of data and I can't see where you change this if at all. I'm trying to access 5 more items in addition to the 3 in your code and I can access all of them if I select only part of the 8 fields at once. For example of the 8 I'm trying to get:

employeeID, SAMAccountName, Mail, DisplayName, sn, givenName, department & userAccountControl


I can get any 5-6 but if I try for 6 to 8, depending on the combination I get an error.

Thoughts?

Kindest Regards,

Just say No to Facebook!
Brian ODwyer
Brian ODwyer
Grasshopper
Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)

Group: General Forum Members
Points: 16 Visits: 31
I found that to be true as well, think it is something to do with the string length, used * to just pull all the columns and save on the string length instead of directly naming then in the select. Tried increasing the string length from 255 to 512 and it did not work. Will research it.
Brian ODwyer
Brian ODwyer
Grasshopper
Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)Grasshopper (16 reputation)

Group: General Forum Members
Points: 16 Visits: 31
Definite 255 char limit. See http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=65584

I used the function to get around and loop through

declare @Apptemp3 table (BSamName varchar(255),
BDisplayName varchar(255),
BPhone varchar(100),
BEMail varchar(255),
BFirstName varchar(100),
BLastName varchar(100))



DECLARE @sChar char(1)
declare @body varchar(8000)
DECLARE @nAsciiValue smallint


SELECT @nAsciiValue = 65

WHILE @nAsciiValue < 91
BEGIN

SELECT @sChar= CHAR(@nAsciiValue)

SET @body = (select dbo.fnSprintf('SELECT sAMAccountName, displayName, mail, telephoneNumber, sn, givenName FROM OPENQUERY( ADSI, ''SELECT displayName, sAMAccountName, mail, telephoneNumber, sn, givenName FROM ''''LDAP://dc=cchcs,dc=ldap''''WHERE objectCategory = ''''Person'''' AND SAMAccountName = ''''%s*'''''' )', @SChar +'*', default))

INSERT @Apptemp3
EXEC( @body)

SELECT @nAsciiValue = @nAsciiValue + 1
END

Select ISNULL(Upper(BSamName),'NoSamID'),ISNULL(BDisplayName,'NoDName'),ISNULL(BPhone,'NoPhone'),ISNULL(BEMail,'Nomail'),ISNULL(BFirstName,'NoFname'),ISNULL(BLastName,'NoLname') from @Apptemp3
order by BSamName
Go


Permissions

You can't post new topics.
You can't post topic replies.
You can't post new polls.
You can't post replies to polls.
You can't edit your own topics.
You can't delete your own topics.
You can't edit other topics.
You can't delete other topics.
You can't edit your own posts.
You can't edit other posts.
You can't delete your own posts.
You can't delete other posts.
You can't post events.
You can't edit your own events.
You can't edit other events.
You can't delete your own events.
You can't delete other events.
You can't send private messages.
You can't send emails.
You can read topics.
You can't vote in polls.
You can't upload attachments.
You can download attachments.
You can't post HTML code.
You can't edit HTML code.
You can't post IFCode.
You can't post JavaScript.
You can post emoticons.
You can't post or upload images.

Select a forum

































































































































































SQLServerCentral


Search