从 SQL Server 查询 LDAP - 最佳实践

发布于 2024-12-12 12:50:35 字数 2793 浏览 4 评论 0原文

我想知道当前用于更新用户 (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 条记录时才有效,这在一家大公司可能需要大量的 UNION...至少这是我最初的想法在它上面。

从 SQL Server 2005 查询 Active Directory

提前感谢大家!!!

<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>

I'm wondering if the current process I'm using to update a table of user's (tblUsers) Windows ID's (NTID) is a good method. I'm wondering because LDAP will only return 1000 rows I believe, so that prevents me from just doing it all in one query.

tlbUsers has about 160,000 rows. I'm querying LDAP to update the NTID of each record in tblUsers. I'm using a linked server to ADSI to view LDAP data. My process uses two stored procedures, one for getting a WindowsID from LDAP (LdapPackage.GetUserNTID), another for updating the rows in tblUsers (LdapPackage.UpdateUserNTID).

The code below works for updating the table, however, it's pretty slow. It would seem to me this isn't the best way of doing it, that if I wanted to do a batch update like this from LDAP, there should be a simpler way than updating a record at a time.

This previous post gave an interesting example using UNION's to get around the 1000 record limit, but it only works if each query returns less than 1000 records, which at a large company would probably require lots of UNIONS... at least that's my initial take on it.

Querying Active Directory from SQL Server 2005

Thanks in advance guys!!!

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以可爱出名 2024-12-19 12:50:35

我的解决方案是让系统管理员增加链接服务器对 LDAP 的记录限制。我更希望能够确定某种 SQL Server 接口,例如 Oracle 所具有的接口……所以也许我将来会实现这一点。

my solution here was to have my that linked servers record limit to LDAP increased by the system admin. I would have preferred to have identified some sort of SQL Server interface like Oracle appears to have... so maybe I'll get to that in the future.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文