powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / AV на присвоении текста в AdoQuery.SQL.Text Delphi7
27 сообщений из 27, показаны все 2 страниц
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127224
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, коллеги! Получаю список компьютеров из Active Directory при помощи TADOConnection и TADOQuery.

По тексту все элементы создаются и в конце работы освобождаются. Сам список компьютеров из AD также удается получить, но есть две проблемы:

1). при каждом выполнении кода получаю ошибку
Код: sql
1.
Access violation Access violation at address 00448A07 in module ExpDataFromAD.exe. Read of address 00000000


Она происходит на строке присвоения текста AdoQuery.SQL.Text:= vSQL;
Но данные запроса при этом приходят.
При этом и AdoQuery парой строчек выше создан и vSQL это существующая строковая переменная.

2). если крутить код чтения списка в приложении по таймеру, то через некоторое количество выполнении происходит out of memory.
Я предполагаю, что причина в этой самой AV, из-за нее память утекает.

Прошу совета, как бороть такую проблему?

Код программы такой:
Код: pascal
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.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
CoInitializeEx(nil, COINIT_MULTITHREADED);

  try
    try
      vAdoConn:=TADOConnection.Create(nil);
      vAdoConn.LoginPrompt:=false;

      vAdoConn.ConnectionString:='Provider=ADsDSOObject;Password='+aPassword+';User ID='+aLogin+';Encrypt Password=False;Mode=Read';
      vAdoConn.Open;
    except
      on e:exception do
      begin
        WriteLog(vErrorFile, 'Export PC List from AD error: '+e.message);
        exit;
      end;
    end;

    try
      vAdoQuery:=TADOQuery.Create(nil);
      vAdoQuery.Connection:=vAdoConn;

      LastDate:= now - 15;
      vObjectName:='computer';
      vSQL:='select Name, operatingsystem, operatingSystemVersion, objectguid, useraccountcontrol, whenCreated, distinguishedName '+
            'from '+quotedstr('LDAP://'+vDomainName)+' where objectClass='+quotedstr(vObjectName);
      vSQL:= vSQL + ' and whenCreated > '+ quotedstr(GetDTString(LastDate)); 

      vAdoQuery.Close;
      vAdoQuery.SQL.Text:=vSQL;
      vAdoQuery.Open;
      if NOT vAdoQuery.IsEmpty then //exit;
      begin
        setlength(PCMas, vAdoQuery.RecordCount);
        vAdoQuery.First;
        j:= 0;
        while not vAdoQuery.eof do
        //for j:= 0 to vAdoQuery.RecordCount-1 do
        begin
          for i:= 0 to vAdoQuery.FieldCount-1 do
          begin
            vFieldVal:=vAdoQuery.Fields[i].AsString;

            if vAdoQuery.Fields[i].FieldName='Name' then
              PCMas[j].PCName:= vFieldVal;
          end;

          vAdoQuery.Next;
          inc(j);       
        end;
      end;      

      vAdoQuery.Close;
    except
      on e:exception do
      begin
        WriteLog(vErrorFile, 'Export PC List from AD vAdoQuery execute error: '+e.message);
      end;
    end;
  finally
    if (vAdoQuery <> nil) then vAdoQuery.Free;
    vAdoConn.Free;
  end;
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127228
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShield,
Если на присвоении текста исключение, то до открытия собственно запроса дело доходить не должно.
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127230
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vlad F, у меня при запуске под отладчиком ошибка вываливалась на этой строке vAdoQuery.SQL.Text:=vSQL;
но потом продолжает дальше выполняться...

и память утекает, хоя в finally есть освобождение компонент...
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127232
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShieldПрошу совета, как бороть такую проблему?

Начать хоть немного думать мозгом о том как твой код работает не предлагать?..

Код: sql
1.
vAdoQuery.Close;


Закрывается запрос который никогда не открывался.

Код: sql
1.
vAdoQuery.First;


Возврат к первой записи набора данных, который никогда с неё и не сходил.

Код: sql
1.
2.
3.
setlength(PCMas, vAdoQuery.RecordCount);

while not vAdoQuery.eof do


Резервируется место по числу RecordCount, а заполняется пока не надоест.
Естественно массив переполняется, затирая всё, чему не повезло оказаться в куче
после него.

Код: sql
1.
2.
3.
4.
5.
6.
7.
for i:= 0 to vAdoQuery.FieldCount-1 do
           begin
             vFieldVal:=vAdoQuery.Fields[i].AsString;

             if vAdoQuery.Fields[i].FieldName='Name' then
               PCMas[j].PCName:= vFieldVal;
           end;


Значения всех полей заносятся в одну переменную, которая потом в большинстве
случаев не используется. О FieldByName ты когда-нибудь слышал?..

Код: sql
1.
if (vAdoQuery <> nil) then vAdoQuery.Free;


Проверка переменной на значение, которое ей никогда никем не присваивалось.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127236
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShield

и память утекает, хоя в finally есть освобождение компонент...

Однако нет SetLength(PCMas, 0).
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127246
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov, благодарю за замечания. Я их учту.
Тем не менее close и first для ADOQuery в данном коде просто избыточны (т.к. компоненты создаются и разрушаются), но к ошибке они не приведут.

Переменных при разборе запроса больше берется (точнее, используются все, какие в query были), я при выкладке на форум код сократил. можно по имени брать, а можно и просто перечислить. так или иначе все поля разбираются.

if (vAdoQuery <> nil)
значение nil может быть, если подключение ADOCon не прошло успешно. Поэтому такая проверка ИМХО выглядит нужной.

Код: pascal
1.
while not vAdoQuery.eof do


тут все равно выберется не больше чем есть в выборке. Согласен, правильнее или динамически массив увеличивать внутри while или вместо while использовать for j:= 0 to vAdoQuery.RecordCount-1 do
Но если бы дело было в разном количестве элементов массива, то ошибка бы другая была.
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127249
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vlad F, Вы имеете ввиду зануление массива в начале процедуры или в finally?
данный массив PCMas подается на вход процедуры с параметром out. Он используется в коде, вызывающем процедуру и там же после использования и зануляется. хотя его зануление в начале процедуры можно поставить. но по коду дальше, размер массива все равно будет сделан равным RecordsCount нового запроса...
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127252
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShieldзначение nil может быть, если подключение ADOCon не прошло
успешно.

Откуда? Если нет явного присвоения - значение переменной не определено и может
быть любым. Исключение составляют переменные типа интерфейс и строка.

SilverShieldтут все равно выберется не больше чем есть в выборке.

А вот тут ты глубоко заблуждаешься. RecordCount не обязано возвращать реальное
количество записей в выборке, допускается возвращение -1 или текущего
отфетченного батча.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127299
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov, про nil принято. Правильнее будет if assign использовать? для проверки, что компонента создана.

> RecordCount не обязано возвращать реальное количество записей в выборке

Принято, это переделаю на увеличение массива внутри цикла while not vAdoQuery.eof do
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127302
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По поводу Access violation эти действия не помогли. Оно также происходит на строке vAdoQuery.SQL.Text:=vSQL;
при этом код также как и раньше продолжает выполняться дальше и возвращается результат запроса.
что за чудеса, откуда может расти AV на ровном месте...
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127308
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не нравится мне вот это
SilverShield
Код: pascal
1.
CoInitializeEx(nil, COINIT_MULTITHREADED);

применительно к ADO.

И еще вопрос - приложение, случайно, не многопоточное? А если да, то где объявлено vAdoQuery?
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127313
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShieldПравильнее будет if assign использовать?

Нет. Это то же самое.

Переменные надо всегда инициализировать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127321
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShield
...переделаю на увеличение массива внутри цикла while not vAdoQuery.eof do

Ты эта, - уже ослабь фантазию маленько.
Перед .RecordCount вызови .FetchAll, ну а если его там нет, то .Last/.First, как вариант замены.
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127357
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_, приложение в котором тестирую, однопоточное. Компоненты ADOConnection и ADOQuery обявлены в var той процедуры, где дальше с ними идет работа. Т.е. они по сути локальные.
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127358
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vlad F, благодарю. Действительно, можно и так.
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127360
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShield,

код программы не полный, нужно видеть все объявления переменных, помести все в дпр и запости сюда.
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127383
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zelius, прикрепил юнит с процедурой. Код основной программы в упрощенном виде:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure TForm1.Button1Click(Sender: TObject);
var
  NewPCMas: TNewPCMas;  
  LastCheckTime: Tdatetime;
  aLogin, aPassword: string;
begin
  LastCheckTime:= Now-2190;
  aLogin:= 'domain\testuser';
  aPassword:= 'userpassword';

  GetNewPCFromAD(LastCheckTime, aLogin, aPassword, NewPCMas);
end;
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127389
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShield,

GetUserNameExA - функция, а не процедура
GetUserNameExA
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127402
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zelius, изменил ее объявление на функцию. К сожалению, на AV это не влияет...
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127403
Belotsky Serge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SilverShield,
А не попробовали? Что-то меня смущает присвоение прямо в .Text (взято из справки по Delphi). Просто выполнить один Add(vSQL).
Код: pascal
1.
2.
3.
4.
5.
6.
with ADOQuery1 do begin
with SQL do begin
Clear;
Add(vSQL);
end;
Open;
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127410
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Belotsky Serge
Что-то меня смущает присвоение прямо в .Text

Зря смущает
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127421
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторОна происходит на строке присвоения текста AdoQuery.SQL.Text:= vSQL;
Почему бы перед присвоением не вывести текст запроса на экран ?
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127425
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShield,

проверил код у себя на Д7, у меня AV не выпадает. имхо, попробуй вынести сам в отдельный проект где больше ничего нет. если не поможет, то возможно проблемы с установкой дельфи.
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127438
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Delphi Rio - работает
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127439
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
del
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40127451
Gerasimenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SilverShield,

для чистоты эксперимента, попробуй TADOQuery, заменить на TADODataSet или на TADOCommand (и _RecordSet)
...
Рейтинг: 0 / 0
AV на присвоении текста в AdoQuery.SQL.Text Delphi7
    #40129579
SilverShield
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, вопрос закрыт. Сам AV побороть так и не удалось (проект пересобирал в другой инсталляции D7, компилил отдельно в XE3, ошибка все равно оставалась).
Но утечка памяти в последнем варианте кода устранена. В итоге приложение работает, результаты выдает, в try except ошибка глушится. Оставлю пока так.
Благодарю всех за помощь!
...
Рейтинг: 0 / 0
27 сообщений из 27, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / AV на присвоении текста в AdoQuery.SQL.Text Delphi7
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]