Entwickler-Ecke

Datenbanken - Active Directory abfragen


mcbain - Mo 19.12.11 16:42
Titel: Active Directory abfragen
Hallo, ich möchte gerne alle User unseres AD abfragen. Das funktioniert auch über ADO recht gut. Nur werden mir leider 1.000 Benutzer immer ausgegeben. Wir haben aber um die 6.000 User.
Nun verwende ich folgenden Code, um alle User zu bekommen. Das Stichwort ist Page Size:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
var SQL,DOMAIN: WideString;
    t:_recordset;
begin
 
    DOMAIN := '''LDAP://dc=xx,dc=xx-xxxxxxx, dc=de''';
    try
      Screen.Cursor := crHourGlass;
      memAD.Close;
      memAD.Open;

      cmd.Connection := adoconnection1;
      adoconnection1.Connected:=true;
      SQL := 'select sn,givenname,cn from '+DOMAIN+' where objectclass='+'''user'''+' and objectclass<>'+'''computer'' ORDER by cn';
      cmd.CommandText :=SQL;   //Hier wirft Compiler eine Fehlermeldung
   
      cmd.Properties.Item['Page Size'].Value := 10;
      t:=cmd.Execute;


      memad.DisableControls;
      while t.EOF = false do
      begin    
         memAD.Append;
         if t.Fields[2].Value <> NULL then
            memAD.FieldByName('sn').AsString := t.Fields[2].Value;
         if t.Fields[1].Value <> NULL then
            memAD.FieldByName('givenname').AsString  := t.Fields[1].Value;
         if t.Fields[0].Value <> NULL then
            memAD.FieldByName('cn').AsString := t.Fields[0].Value;
         memAD.Post;

        t.MoveNext;
      end;
      memAD.EnableControls;

    finally
        Screen.Cursor := crDefault;

    end;


Das ganze funktioniert auch, sprich ich bekomme unsere ca. 6.000 Benutzer in meinem Memtable angezeigt, jedoch wirft der Compiler eine Fehlermeldung an der markierten Stelle. Die Fehlermeldung ist eine EAccessViolation, sprich eine Zugriffsverletzung.

Wäre nett, wenn wenn mir jemand sagen könnte, worin mein Fehler besteht, oder geht es auch einfacher zu lösen?
Gruß
mc


zuma - Mo 19.12.11 16:48

was auch immer "cmd" ist, ich fürchte, du hast das nicht erzeugt ?
Zugriffsverletzung deutet jedenfalls oft auf nicht erzeugte Objekte hin ...


mcbain - Mo 19.12.11 16:50

Doch ist erzeugt.
cmd ist vom Typ TADOCommand,
adoConnection1 ist vom TADOConnection.
Alle liegen auf meiner Form und sind somit natürlich auch erzeugt zu dem Zeitpunkt.


bummi - Mo 19.12.11 17:15

Ich würde ein Adodatset nehmen.
Da der Fehler Auftritt wenn Du Deine Datensätze schon hast, kann er eigentlich nur auftreten wenn Du die Funktion ein zweites mal aufrufst?
Bein einem Adodataset würde ich sagen schließe es bevor Du CMD setzt, so wirst Du die Connection schließen und wieder öffnen müssen.


mcbain - Di 20.12.11 10:37

Danke für die Antwort.
Ich habe mein Problem nun so gelöst:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
...
var rs, conn, com: Variant;
    i: Integer;
begin
  DOMAIN := '''LDAP://dc=xx,dc=xx-xxxxxxxxx,dc=de''';
  CoInitialize(nil); 
  try
    conn := CreateOleObject('ADODB.Connection');
    com := CreateOleObject('ADODB.Command');
    conn.Provider := 'ADsDSOObject';
    conn.open;

    com.ActiveConnection := conn;
    Com.CommandText := 'select cn,givenname,sn from '+Domain+' where objectclass='+'''user'''+' and objectclass<>'+'''computer'' ORDER by cn';

    com.Properties['Page Size'] := 10;
    Com.Properties['Timeout'] := 600;
    Com.Properties['Cache Results'] := False;
    Com.Properties['Size Limit'] := 200;
    rs := COm.Execute;

    While Not rs.EOF do
    begin
      memTable.Append;
      For i := 0 To rs.Fields.Count - 1 do
      begin
        if not VarIsNull(rs.Fields[i].Value) then
           memTable.Fields.Fields[i].AsString := rs.fields[i].Value;
        memTable.Post;
        if i <> rs.fields.count - 1  then
           memTable.Edit;

      end;
      rs.MoveNext;
    
    end;

    Rs := NULL;
  finally
    CoUninitialize;
    com := NULL;
    conn.Close;
    conn := NULL;

  end;