2011-12-21 2 views
3

При попытке запросить AD для пользователей, которые я получаю следующее сообщение об ошибке:Ошибка: Не удается получить строку из OLE DB провайдера «ADsDSOObject» для связанного сервера «ADSI»

не удалось получить строку из поставщика OLE DB «ADsDSOObject «для связанного сервера« ADSI ».

Я предполагаю, что проблема связана с пределом 1000 строк (или 901 строк в SqlServer 2008). Я могу задать запрос, но я ищу обходное решение, которое позволит мне получать более 1000 за раз.

Если это помогает, я использую SqlServer 2008 R2. и вот мой запрос

SELECT samaccountname AS Account, ISNULL(givenName, '''') AS givenName, ISNULL(SN, '''') AS SN, ISNULL(DisplayName, '''') as DisplayName, ISNULL(Title, '''') AS Title 
         FROM OpenQuery(ADSI, 
         'SELECT SamAccountName, givenName, SN, DisplayName, Title 
         FROM ''LDAP://corpdomain.corp'' 
         WHERE objectClass = ''User'' and (SN = ''*'' or givenName = ''*'')') 

Любые идеи?

EDIT - При дальнейшем осмотре я понял, что не могу правильно запросить этот запрос. У кого-нибудь есть какие-либо советы по решению, которое позволит мне опубликовать результаты или обходной путь, который позволит мне вернуть более 901?

+0

Какая у вас конечная цель в этом отношении? Лучшим решением может быть вовсе не делать этого. Например, я работал над проблемами с этим типом запросов в некоторых наших системах, заменив его пакетом SSIS в одном случае и источником данных отчета, который напрямую связан с AD в SSRS в другом случае. – JamieSee

+0

Спасибо Джеймсу, я переоценил конечную цель и нашел лучший способ. Мы хотели добавить атрибуты пользователю AD для целей нашего приложения, поэтому теперь мы просто используем пакетное задание для извлечения пользователей AD и хранения их в БД. – SDeezy

+0

Возможный дубликат [Получить> 901 строк из связанного сервера SQL Server 2008 с Active Directory] (http://stackoverflow.com/questions/5661371/retrieve-901-rows-from-sql-server-2008-linked-server- to-active-directory) –

ответ

2

Проблема

When I attempt to query AD for users I receive the following error:

Cannot fetch a row from OLE DB provider "ADsDSOObject" for linked server "ADSI".

I assume the issue due to the 1000 row limit (or 901 rows in SqlServer 2008). I can page the query >but I am looking for workaround that would allow me to retrieve more than 1000 at a time.

In case it helps, I am using SqlServer 2008 R2. and here is my query >

SELECT samaccountname AS Account, ISNULL(givenName, '''') AS givenName, ISNULL(SN, '''') AS SN, ISNULL(DisplayName, '''') as DisplayName, ISNULL(Title, '''') AS Title 
        FROM OpenQuery(ADSI, 
        'SELECT SamAccountName, givenName, SN, DisplayName, Title 
        FROM ''LDAP://corpdomain.corp'' 
        WHERE objectClass = ''User'' and (SN = ''*'' or givenName = ''*'' 

Any ideas?

EDIT - Upon further inspection I realized I am not able to properly page this query either. Does >anyone have any tips on a solution that will allow me to page the results or a workaround that will >allow me to return more than 901?

Мой обходной

Я просто решил такую ​​же проблему, с которой сталкиваются меня, применяя пейджинг оптимально (и я успешно смог получить около 50 тыс. логинов из AD и не хватает для получения одной учетной записи входа из доменов AD):

Вам необходимо обойти ограничение запроса ADSI, перейдя по символам атрибутов. См. Решение здесь: http://www.sqlservercentral.com/Forums/Topic231658-54-1.aspx#bm1249991

Ошибка была разрешена путем записи SELECT TOP 901 ... В МЕСТАХ ТОЛЬКО SELECT.

И да, эта проблема связана с использованием SqlServer 2008 R2.Эта проблема возникла у меня после миграции базы данных с 2005 по 2008 год, потому что в SQL Server 2008 существует предел в 901 строку, которая была 1000 в SQL Server 2005 (разница в том, что нам нужно написать select TOP 901, который не был требуемый в SQL Server 2005, иначе программа завершится с ошибкой)

+0

. 2012 год имеет такую ​​же проблему? – th1rdey3

3

От вашего ответа на мой комментарий это звучит как пакет SSIS, запущенный заданием SQL-агента, будет идеальным способом. Вот как вы можете получить доступ к Active Directory в SSIS:

  1. Создать новый SSIS проект
  2. Добавление задачи потока данных в потоке управления.
  3. Перейдите на вкладку «Поток данных».
  4. Перетащите источник ADO NET из панели инструментов в поток данных.
  5. Дважды щелкните источник ADO NET.
  6. Нажмите кнопку «Создать» рядом с диспетчером соединений OLE DB.
  7. Нажмите кнопку «Создать» в диалоговом окне «Настройка ADO.NET Connection Manager» .
  8. Нажмите на указательную стрелку вниз в раскрывающемся списке Провайдер.
  9. Найдите .Net-провайдеров для OleDb в списке и дважды щелкните по нему.
  10. Найдите поставщика OLE DB для служб Microsoft Directory в списке и дважды щелкните его.
  11. Нажмите кнопку OK.
  12. В сервере или имени файла установите ActiveDirectory.
  13. Выделите ActiveDirectory в соединениях данных.
  14. Нажмите кнопку OK.
  15. Измените режим доступа к данным на команду SQL.
  16. В текстовом поле команды SQL введите <LDAP://DC=domain,DC=tld>;(&(objectClass=User)(objectCategory=Person));distinguishedName,displayName,sn,givenName,middleName,mail,telephoneNumber;subtree.
  17. Изменение домена и tld на соответствующие идентификаторы для вашего домена и добавление любых других соответствующих элементов пути LDAP.
  18. Добавьте в запрос любые другие соответствующие атрибуты ActiveDirectory.
  19. Нажмите кнопку OK.
  20. Вы увидите сообщения об ошибках, указывающие, что тип данных «System.Object» не поддерживается. Их можно игнорировать.
  21. Нажмите кнопку «ОК» в диалоговом окне предупреждения.
  22. Щелкните правой кнопкой мыши по источнику ADO NET.
  23. Нажмите «Свойства».
  24. Изменить ValidateExternalMetadata на False.

Возможно, вы также захотите выполнить следующие шаги, но имейте в виду, что если вы это сделаете и у вас есть атрибут Active Directory длиной более 4000 символов, он будет усечен в потоке данных.

  1. Щелкните правой кнопкой мыши по источнику ADO NET.
  2. Нажмите «Показать расширенный редактор».
  3. Перейдите на вкладку «Свойства ввода и вывода».
  4. Разверните выходной источник ADO NET.
  5. Развернуть выходные столбцы.
  6. Для каждого столбца измените тип DataType на строку Unicode [DT_WSTR] и установите длину до 4000.
  7. Нажмите кнопку OK.
  8. Дважды щелкните источник ADO NET, перейдите к выводу ошибки.
  9. Выделить все значения для строк под Trunctation.
  10. Элемент списка
  11. В разделе Установить это значение в выбранные ячейки выберите Игнорировать сбой.
  12. Нажмите кнопку «Применить».
  13. Нажмите кнопку OK.

Обратите внимание, что этот формат запроса также поддерживается:

SELECT  distinguishedName, displayName, sn, givenName, middleName, mail, telephoneNumber 
FROM   'LDAP://DC=domain,DC=tld' 
WHERE  objectClass = 'User' AND objectCategory = 'Person' 

Смотрите статью MSDN Microsoft OLE DB Provider for Microsoft Active Directory Service для получения дополнительной информации о форматах запросов, поддерживаемых провайдером.

+0

Спасибо за подробное объяснение. Я обнаружил, что компания запускает ежедневное консольное задание, которое извлекает всех пользователей объявлений в SQL Server. Решила проблему. Я не пробовал это, но похоже, что это сработает ... так что это выглядит хорошим ответом на меня. Благодаря! – SDeezy

0

Я решил это, используя другое сообщение от Магнуса Рейтера - просто подумал, что я дал y'all ссылку, потому что это просто и остроумно!

Он сделал 2 запроса, присоединившись к ним с помощью UNION, но для первого выбрал все имя sAMAccountname m. Конечно, если вы обнаружите, что ваша середина не является буквой «m», вы можете настроить ее соответствующим образом, но, как правило, если у вас около 1000-2000 записей, она будет «m».

Retrieve >901 rows from SQL Server 2008 linked server to Active Directory

0

я ударил эту проблему тоже, и не нравится обычное решение размещенного пейджинговой по первой букве имени учетной записи. Это будет означать 26 отдельных вызовов AD, а также может по-прежнему потенциально потерпеть неудачу, потому что с большим доменом у него может быть более 901 учетных записей, начинающихся с того же первого письма, особенно если вы смотрите на учетные записи компьютеров, которые, вероятно, следуют некоторым систематическим именования с использованием той же первой буквы ...

Я немного поиграл, и я обнаружил, что если вы закажете openquery с помощью uSNCreated и поместите предложение 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, givenName, sn, userAccountControl, lastLogon, displayName, samaccountname, 
       title, department, physicalDeliveryOfficeName, info, mail, telephoneNumber, 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  
     , GivenName 
     , FamilyName 
     , DisplayName 
     , Title   
     , Department 
     , Location  
     , Email   
     , Phone   
     , QuickDial  
     , Mobile   
     , Info   
     , 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 
Смежные вопросы

 Смежные вопросы