-
На сервере COM есть функция, которая конвертирует значения результата выборки из TADOQuery в массив значений типа Variant.
function GetQueryResult(Query: TADOQuery): OleVariant; var i, j: integer; begin if Query.Active then Query.Close; try Query.Open; Query.First; Result := VarArrayCreate([0, Query.FieldCount - 1, 0, Query.RecordCount-1], varVariant); while not Query.Eof do begin for j := 0 to Query.RecordCount - 1 do begin for i := 0 to Query.FieldCount - 1 do Result[i, j]:=Query.Fields[i].Value; Query.Next; end; end; finally Query.Close; end; end;
Вопрос. Нужно ли, а если нужно, то как правильно использовать VarArrayLock и VarArrayUnlock в этой функции? Спасибо.
-
> Нужно ли
Не нужно.
А в связи с чем возникло сомнение ?
> Query.First;
Это лишнее.
> Query.RecordCount
Почитай внимательно Note в справке к методу TADOCustomDataSet.RecordCount
-
> А в связи с чем возникло сомнение ? Прочитал о инициализации больших массивов с помощью функции VarArrayLock() и процедуры VarArrayUnlock()... вот и возникли сомнения.
> Query.First;
А что? При открытии Query мы всегда будем на 1 записи?
>Почитай внимательно Note в справке к методу TADOCustomDataSet.RecordCount
Читал... "Indicates the total number of records in the recordset..." "...Should ADO not be able to determine that actual number of rows, RecordCount will return a value of negative one (-1)." Тут немножко не ясно...
-
> "...Should ADO not be able to determine that actual number > of rows, RecordCount will return a value of negative one > (-1)."
это значит, что нельзя быть уверенным, что это св-во содержит реальное количество записей. Лучше пользоваться с-вами Bof и Eof.
-
> umbra © (01.10.07 18:14) [3]
Мне нужно количество записей для создания массива. Неужели самому считать?
i:=0; while not Query.Eof do begin inc(i); Query.Next; end;
???
-
> При открытии Query мы всегда будем на 1 записи?
А куда мы денемся с подводной лодки ?)
> Прочитал о инициализации больших массивов с помощью функции > VarArrayLock() и процедуры VarArrayUnlock()
Для простых типов VarArrayLock() в целях инициализации может и помогла бы, но у тебя Variant.
> Неужели самому считать?
Сходи в конец НД (Last), затем вернись в начало (First), вот тогда только получишь более-менее достоверное (зависит от многих условий) значение RecordCount.
-
Один RecordCount убрал :). Действительно было лишнее.
function GetQueryResult(Query: TADOQuery): OleVariant; var i, j: Integer; begin if Query.Active then Query.Close; try Query.Open; Result := VarArrayCreate([0, Query.FieldCount - 1, 0, Query.RecordCount-1], varVariant); j := 0; while not Query.Eof do begin for i := 0 to Query.FieldCount - 1 do Result[i, j]:=Query.Fields[i].Value; Query.Next; Inc(j); end; finally Query.Close; end; end;
Как поступить с инициализацией массива?
Query.Open; Query.Last; Query.First;
И только тогда можно пользоваться RecordCount?...
-
> только тогда можно пользоваться RecordCount?
Да.
А собссно зачем такие сложности ?
Почему не использовать TDataSetProvider ? Он все сделает сам - получит весь НД из твоего TADOQuery, упакует его в массив и вернет этот массив через св-во Data.
-
> А собссно зачем такие сложности ?
Дело в том, что по условию задания клиенты этого сервера приложений должны быть написаны на С#...
-
Ну и что ?
Св-во DataSetProvider.Data точно такой же массив, описанный OeVariant-типом, только внутренний формат специфичен.
-
> Для простых типов VarArrayLock() в целях инициализации может и помогла бы, но у тебя Variant. Тоесть, если у меня будет массив значений типа Integer, то тогда будет справедливо писать
var i: Integer; A: OleVariant; P: PIntegerArray; begin A := VarArrayCreate([0, 10000], varInteger); P:=VarArrayLock(A); try for i := 0 to 10000 do P^[i] := SomeIntegerValue; finally VarArrayUnlock(A); end; end;
-
> Св-во DataSetProvider.Data точно такой же массив, описанный OeVariant-типом, только внутренний формат специфичен. А как я узнаю этот формат в С#? Это старая тема. Например, http://pda.delphimaster.net/?id=1185269441&n=8. Из Вашего поста <Сергей М. © (29.08.07 09:29) [23]> я понял, что только через свой VarArray необходимо передавать DataSet, чтобы С# мог принять его...
-
> yuray © (02.10.07 11:16) [10]
Иллюстрация : v: OleVariant;
pb: PByteArray;
..
v := VarArrayCreate([1, 4], varByte);
pb := VarArrayLock(v);
PInteger(p)^ := $04030201;
VarArrayUnlock(v);
showmessage(inttostr(v[1]) + ' ' + inttostr(v[2]) + ' ' + inttostr(v[3]) + ' ' + inttostr(v[4]));
> как я узнаю этот формат
Например, проанализировав код метода TDataSetProvider.GetData
-
> Сергей М.
Спасибо за ответы. Буду анализировать код метода TDataSetProvider.GetData...
|