Запрос LDAP из SQL Server - наилучшая практика - PullRequest
1 голос
/ 29 октября 2011

Мне интересно, является ли хорошим способом текущий процесс, который я использую для обновления таблицы пользовательских идентификаторов Windows (NTID). Мне интересно, потому что LDAP вернет мне только 1000 строк, поэтому я не могу делать все это в одном запросе.

tlbUsers имеет около 160 000 строк. Я запрашиваю LDAP для обновления NTID каждой записи в tblUsers. Я использую связанный сервер с ADSI для просмотра данных LDAP. Мой процесс использует две хранимые процедуры, одну для получения WindowsID из LDAP (LdapPackage.GetUserNTID), другую для обновления строк в tblUsers (LdapPackage.UpdateUserNTID).

Приведенный ниже код работает для обновления таблицы, однако он довольно медленный. Мне кажется, это не лучший способ сделать это, что если бы я хотел сделать пакетное обновление, подобное этому, из LDAP, то должен быть более простой способ, чем обновление записи за раз.

В этом предыдущем посте был приведен интересный пример использования UNION для преодоления предела в 1000 записей, но он работает только в том случае, если каждый запрос возвращает менее 1000 записей, что в крупной компании, вероятно, потребует много UNIONS ... по крайней мере, это мой первоначальный взгляд на это.

Запрос Active Directory из 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 Ответ

1 голос
/ 16 ноября 2011

Мое решение здесь состояло в том, чтобы системный администратор увеличил предел записи для этих связанных серверов на LDAP.Я бы предпочел идентифицировать некоторый интерфейс SQL Server, как, по-видимому, у Oracle ... так что, возможно, я доберусь до этого в будущем.

...