从SQL Server查询LDAP - 最佳实践

时间:2011-10-29 01:22:08

标签: sql-server sql-server-2008 tsql active-directory ldap

我想知道我用来更新用户(tblUsers)Windows ID(NTID)表的当前进程是否是一个好方法。我想知道因为LDAP只会返回我认为的1000行,所以这使我无法在一次查询中完成所有操作。

tlbUsers大约有160,000行。我正在查询LDAP以更新tblUsers中每条记录的NTID。我正在使用ADSI链接服务器来查看LDAP数据。我的进程使用两个存储过程,一个用于从LDAP获取WindowsID(LdapPackage.GetUserNTID),另一个用于更新tblUsers中的行(LdapPackage.UpdateUserNTID)。

下面的代码适用于更新表格,但是,它很慢。在我看来,这不是最好的方法,如果我想从LDAP进行这样的批量更新,那么应该有一种比一次更新记录更简单的方法。

这篇上一篇文章给出了一个有趣的例子,使用UNION来绕过1000记录限制,但只有在每个查询返回少于1000条记录时才有效,这在一家大公司可能需要大量的UNIONS ...至少那个我最初的看法。

Querying Active Directory from SQL Server 2005

先谢谢你们!

<code>
CREATE PROCEDURE LdapPackage.GetUserNTID
(
    @EmployeeID INT,
    @OutNTID VARCHAR(20) OUTPUT

)
AS
BEGIN

DECLARE @SQLString NVARCHAR(MAX)
DECLARE @ParmDefinition NVARCHAR(MAX)
DECLARE @LdapFilter NVARCHAR(100)
--DECLARE @NTID   VARCHAR(20)

SET @LdapFilter = 'employeeNumber = ' + CAST(@EmployeeID AS NVARCHAR(20))

SET @SQLString = 'SELECT DISTINCT @pNTID = samAccountName
    FROM  OPENQUERY(LDAP, 
        ''select samAccountName, Mail
        from ''''GC://domain.company.com''''
        where objectClass=''''user'''' AND objectCategory=''''person'''' and ' + @LdapFilter + ''')
    WHERE Mail IS NOT NULL'

SET @ParmDefinition = N'@pNTID varchar(20) OUTPUT'

EXECUTE sp_executesql
@SQLString,
@ParmDefinition,
@pNTID=@OutNTID OUTPUT

--SELECT NTID = @OutNTID

END
</code>

<code>
CREATE PROCEDURE LdapPackage.UpdateUserNTID
AS
BEGIN

    DECLARE @EmployeeID     AS INT
    DECLARE @NTID       AS VARCHAR(20)
    DECLARE @RowCount   AS INT
    DECLARE @SQLString  AS NVARCHAR(MAX)
    DECLARE @ParmDefinition AS NVARCHAR(200)

    SET @RowCount = 1
    DECLARE Persons CURSOR 
        FOR SELECT DISTINCT EmployeeID FROM tblUsers

    OPEN Persons
    FETCH NEXT FROM Persons INTO @EmployeeID
    WHILE @@FETCH_STATUS = 0
    BEGIN
        --GET NTID
        SET @SQLString =N'EXEC LdapPackage.GetUserNTID @pEmployeeID, @pNTID OUTPUT'

        SET @ParmDefinition =N'@pEmployeeID INT, @pNTID VARCHAR(20) OUTPUT'

        EXECUTE sp_executesql
            @SQLString,
            @ParmDefinition,
            @pEmployeeID=@EmployeeID,
            @pNTID=@NTID OUTPUT
        --UPDATE NTID
        /*PRINT 'RowCount = ' + CAST(@RowCount AS VARCHAR(10))
        PRINT 'EmployeeID   = ' + CAST(@EmployeeID AS VARCHAR(20))
        PRINT 'NTID     = ' + @NTID
        PRINT '-----------------------------'*/
        UPDATE tblUsers
        SET NTID = @NTID
        WHERE EmployeeID = @EmployeeID

        SET @RowCount = @RowCount + 1
        FETCH NEXT FROM Persons INTO @EmployeeID
    END
    CLOSE Persons
    DEALLOCATE Persons
END
</code>

1 个答案:

答案 0 :(得分:1)

我的解决方案是让系统管理员增加对LDAP的链接服务器记录限制。我本来希望已经识别出像Oracle似乎有某种类型的SQL Server接口......所以也许我将来会这样做。