Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];

Вниз

Ошибка при удалении записи в ClientDataSet   Найти похожие ветки 

 
Shura ©   (2006-03-09 11:11) [0]

Привет !
Есть следующий набор:
Delphi7 с апдейтами 1 и 1_1, СУБД Sybase.
В программе реализована связка ADOQuery->DataSetProvider->ClientDataSet.
DataSetProvider.ResolveToDataSet:=True.
На экране 2 Grid"а. Один настроен на отображение ClinetDataSet"а, а второй для контроля на ADOQuery. Набор полей в ADOQuery и ClientDataSet"е одинаковый, но в ClientDataSet"е добавлены несколько полей fkInternalCalc для сортировки и фильтрации. Вся работа ведется через ClientDataSet (удаление/добавление). При открытии ClientDataSet"а в нем находится несколько записей. При добавлении туда других записей все нормально, при удалении тоже, но если не удалять первую запись ! Как только удалили первую строку возникает следующий эффект - число записей на экране уменьшается на 1, но первая строка остается пустой. При этом очищаются только поля fkInternalCalc, а базовые вообще не меняются. Дальше опять можно удалить первую запись, но остается все тоже "проглатывание" первой записи. В паралельном Grid"е, завязаном на ADO все отрабатывается нормально, первая запись удаляется корректно.
Изменение свойства AutoCalcFields не помогает.
Спасибо.


 
Nikolay M. ©   (2006-03-09 11:45) [1]


>  В паралельном Grid"е, завязаном на ADO все отрабатывается
> нормально, первая запись удаляется корректно.


Начнем с простого: Grid.Refresh/Invalidate не спасает?

Кстати, а зачем DataSetProvider.ResolveToDataSet:=True?


 
sniknik ©   (2006-03-09 11:49) [2]

> В программе реализована связка ADOQuery->DataSetProvider->ClientDataSet.
зачем? в смысле, тебе ClientDataSet реально необходим?

это не по ошибке, просто он здесь лишний, и не вижу смысла искать глюк в "пятой ноге" у собаки... оставь четыре, как положено, и возможно все "само собой"(/при переделке на adoшный рекордсет) в норму придет.


 
Shura ©   (2006-03-09 12:23) [3]

to Nikolay M.
>Начнем с простого: Grid.Refresh/Invalidate не спасает?
Не спасает.
>Кстати, а зачем DataSetProvider.ResolveToDataSet:=True?
В ClientDataSet"е необходимо иметь значения автоинкрементных ключевых полей, которые завязаны на другие списки. А это позволяет моментально получать их с сервера через ADO.

to sniknik
>зачем? в смысле, тебе ClientDataSet реально необходим?
ADOQuery возвращает результат работы View, который затем разбирается на расчитываемые поля, по которым нужна сортировка и фильтрация. Причем набор данных довольно большой и сортировка с фильтрацией через SQL занимает много времени, а так через индексы ClientDataSet"а все моментально.


 
sniknik ©   (2006-03-09 12:42) [4]

вот про то и разговор...
> который затем разбирается на расчитываемые поля
делается аналогично и в ado-шном рекордсете

> по которым нужна сортировка и фильтрация.
делается аналогично и в ado-шном рекордсете

> Причем набор данных довольно большой и сортировка с фильтрацией через SQL занимает много времени
и поэтому нужно сначала получить рекордсет на клиента а потом сдублировать данные перегнав в другой аналогичный по возможностям (в используемом плане) рекордсет? лишние операции для уменьшения времени? оригинально.

> а так через индексы ClientDataSet"а все моментально.
а как думаеш это же самое будет делаться через индексы ADODataSet?


 
Nikolay M. ©   (2006-03-09 12:47) [5]


> При этом очищаются только поля fkInternalCalc, а базовые
> вообще не меняются.


А что происходит в OnCalcFields? Обработчик вообще вызывается? "Базовые" значения нормальные, на их основе calculate-поля считаются?


 
Shura ©   (2006-03-09 14:47) [6]

to sniknik

> делается аналогично и в ado-шном рекордсете

Разбор на расчитываемые поля делается, а вот фильтр и сортировка по ним невозможна.


>и поэтому нужно сначала получить рекордсет на клиента а потом >сдублировать данные перегнав в другой аналогичный по возможностям (в >используемом плане) рекордсет? лишние операции для уменьшения >времени? оригинально.

ADOQuery возвращает результат View которое выполняется долго - внутри огромный Select - а его результат несколько сотен записей. Поэтому перегонка их в ClientDataSet не так заметна как время выполнения View.


> а как думаеш это же самое будет делаться через индексы ADODataSet?

У меня не получилось поставить индекс на Calc-поля. Только что проделал - выдается ошибка: "Текущий проводник не поддерживает необходимый интерфейс для функции Index".

to Nikolay M.

> А что происходит в OnCalcFields? Обработчик вообще вызывается?
>  "Базовые" значения нормальные, на их основе calculate-поля
> считаются?

Обработчик вызывается, на их основе Calc-поля считаются. Более того пользователь именно их и видит на экране.
Сейчас еще раз прогнал программу. Выяснилось еще вот, что глюки с пропаданием записей появляются также после того, как будет удалена последняя запись из первоначально открытого recordset"а. Если очистить все записи разом, то все нормально.


 
Nikolay M. ©   (2006-03-09 15:28) [7]


> глюки с пропаданием записей появляются также после того,
>  как будет удалена последняя запись из первоначально открытого
> recordset"а. Если очистить все записи разом, то все нормально.


Грид не девекспрессовский случайно?


 
Shura ©   (2006-03-09 15:39) [8]


> Грид не девекспрессовский случайно?

Нет, я пробовал стандартный и DBGridEh. Одно и тоже.


 
Nikolay M. ©   (2006-03-09 16:02) [9]

А в Д7 нет глюка АДО "EOF or BOF is true", как в Д5?
Слова


> глюки с пропаданием записей появляются также после того,
>  как будет удалена последняя запись из первоначально открытого
> recordset"а.


наводят на такую мысль.


 
Shura ©   (2006-03-09 16:33) [10]


> А в Д7 нет глюка АДО "EOF or BOF is true", как в Д5?

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


 
sniknik ©   (2006-03-09 17:25) [11]

> Разбор на расчитываемые поля делается, а вот фильтр и сортировка по ним невозможна.
расчитываемые поля можно расчитать в View?

> Выяснилось еще вот, что глюки с пропаданием записей появляются также после того, как будет удалена последняя запись из первоначально открытого
> recordset"а.
первая и последняя? подозрительно... а нет случаем в "расчетах" завязки на RecNo?
попробуй сделай такое калькулируемое поле
procedure TForm1.ADODataSet1CalcFields(DataSet: TDataSet);
begin
 DataSet.FieldByName("xxx").AsInteger:= DataSet.RecNo;
end;
и посмотри на значения первой и последней записи. (рекордсет должен быть локальным)

> А в Д7 нет глюка АДО "EOF or BOF is true", как в Д5?
уже в 6-й ничего подобного не было. в 7 тем более.


 
Nikolay M. ©   (2006-03-09 17:45) [12]

Так все-таки есть или нет?


> уже в 6-й ничего подобного не было. в 7 тем более.



> Shura ©   (09.03.06 16:33) [10]
> У меня появляется, хотя патчи от этого ставил и апдейты.


 
sniknik ©   (2006-03-09 17:57) [13]

> Так все-таки есть или нет?

>> У меня появляется, хотя патчи от этого ставил и апдейты.
а у меня не появляется...
(а в 5м было, плюс тогдаже с таймаутами проблемы были, приходилось даже "генофонд" править)
делай выводы сам.


 
Nikolay M. ©   (2006-03-09 18:27) [14]


> (а в 5м было, плюс тогдаже с таймаутами проблемы были, приходилось
> даже "генофонд" править)
> делай выводы сам.


Мне выводы делать не нужно, на 7 я не пишу и описываемых граблей у меня не возникает.


 
Shura ©   (2006-03-10 08:58) [15]


> расчитываемые поля можно расчитать в View?

Можно, еще раза в 2 время увеличится - их там много. :-(. Даже если их и считать во View, то во время работы программы при добавлении новых данных придется View перезапрашивать, чтоб Calc-поля обновить.

> первая и последняя? подозрительно... а нет случаем в "расчетах"
> завязки на RecNo?

Нет, расчитываются части строки из View.

> уже в 6-й ничего подобного не было. в 7 тем более.

Только что проверил еще раз - удалил все записи. В итоге:
Project XXX raised exception class EOleException with message "BOF" или "EOF" имеет значение TRUE и т. д.
в коде:

function TCustomADODataSet.BookmarkValid(Bookmark: TBookmark): Boolean;
begin
 Result := False;
 if Assigned(Bookmark) and not VarIsNull(POleVariant(Bookmark)^) then
 try
   Recordset.Bookmark := POleVariant(Bookmark)^;     <----!!!!!
   CursorPosChanged;
   Result := True;
 except
 end;
end;

Но по-моему ошибка "проглатывается" в блоке Try/Except и дальше не выходит. Внешних проявлений нет, только при запуске из под Delphi.
В принципе Subj происходит при удалении не конкретно первой или последней записи. Опишу по шагам:
1) Открыли данные
2) Удалили все, кроме первой
3) Добавили в набор другие записи
4) Удаляем последнюю "старую" запись - глюк.
Причем все равно какой номер строки будет у "старой" записи - первый или где-то в серединке. Аналогично если удалить блок "старых" записей, а затем ApplyUpdate.
Вчера делал еще вот как - удаляю запись по Delete, делаю ApplyUpdate - на экране все как положено. Но как только делаю ClientDataSet.Refresh, то всплывает удаленная запись, хотя все изменения в базу прошли правильно и локальный набор содержит правильное число записей.


 
sniknik ©   (2006-03-10 11:27) [16]

> Только что проверил еще раз - удалил все записи.
> ...
> Но по-моему ошибка "проглатывается" в блоке Try/Except и дальше не выходит. Внешних проявлений нет, только
> при запуске из под Delphi.
а зачем ты "генофонд" (ADODB) меняеш? в смысле, там дествительно пустой try except, действительно сделано для "поглощения" исключения (видать это проще чем все букмарки отслеживать), но это законченный модуль, отдельный, и если ты его просто используеш то никаких исключений "не выплывет". если же подключил к проекту и меняеш...

в обшем это не тот глюк что в d5 был, это вообще не глюк, а штатная ситуация, так написано.

> Опишу по шагам:
может лучше пример сделаеш? упрощенную модель, 1 таблица 1 view (простейший select * from table), подключение/связка как у тебя с 1м гридом (в чем менять данные), 1 калькулируемое поле... а вот потом последовательность действий при которых воспроизводится глюк.
только если будеш делать то базу не Sybase, лучше Access (у всех есть) или даже виртуальную таблицу (не подключенную к базе а созданную - CreateDataSet, т.к. судя по всему сама база тут не причем). сделаеш присылай, попробую разобраться (в выходные). а эти твои описания совершенно непонятны (это только если кто один в один с такимже сталкивался тогда поймет. но врядли много таких ;)


 
Shura ©   (2006-03-10 11:43) [17]


> а зачем ты "генофонд" (ADODB) меняеш?

В том то и дело, что я ничего не меняю. Да эта ошибка мне и не мешает, дело не в ней.

> может лучше пример сделаеш?

Может попробую. Но пока визуально чистый глюк ClientDataSet"а.


 
sniknik ©   (2006-03-10 11:54) [18]

> Но пока визуально чистый глюк ClientDataSet"а.
проверь
http://www.distribucon.com/midas.html


 
Shura ©   (2006-03-13 14:26) [19]


> проверь
> http://www.distribucon.com/midas.html

Не помогло.
Я собрал тест проект, отправлю по почте. Если будет время глянь, пожалуйста.


 
Shura ©   (2006-03-13 15:50) [20]


> sniknik ©

Не уходит на твой адрес письмо:
LOCAL module(account XXX@XXXX) reports:
account is full (quota exceeded)


 
sniknik ©   (2006-03-13 16:01) [21]

странно, ящик  далеко не полный (full - к этому относится?), меньше 1 процента занято...
либо глюк рамблера либо антиспам сработал.

пошли на тоже имя но на yandex.ru

или лучше выложи на http://webfile.ru/ к примеру да дай сдесь ссылку


 
Shura ©   (2006-03-14 09:04) [22]


> sniknik

Ушло на yandex.ru.


 
sniknik ©   (2006-03-14 10:58) [23]

извини, но это я не буду проверять.
exe файл из инета в любом случае не запущу, смысла даже посылать его не было. а тестовую прогу надо было делать без "левых" компонент (всегда! учти на будущее), переделывать и времени нет, и нет гарантий, что переделанное сохранит глюк который пытаешся продемонстрировать. даже есть хорошая доля вероятности за то, что не сохранит (насколько знаю в некоторых ххххEx-овских гридах встраивают буфер, для всяких сортировок и т.д. (типа основные этого не позволяют)... и что будет при удалении из основного рекордсета записей если xxxxEx "не справится с управлением" и не очистит свой буфер со своими букмарками? правильно будет вышеприведенная ошибка "EOF/BOF" при попытке отрисовать по неудаленным связям из пустого уже рекордсета. возможно? возможно! по основному глюку не знаю, но тоже возможно есть связь).

кстати, заранее, не надо предлагать мне его "доставить" (или "сооблазнять" "прелестями" этого компонента).
http://delphimaster.net/view/2-1141906227/


 
Shura ©   (2006-03-14 11:29) [24]


> sniknik

ОК. Пересоберу. А "соблазнять" действительно не буду :-).


 
sniknik ©   (2006-03-14 18:07) [25]

ужас... код лучше любого фильма ужаса, что я видел. ;о)

в потоке единственный(!!!) валидный оператор (ExitProcess(0);) все остальнее... ТАК ДЕЛАТЬ НЕЛЬЗЯ. поток вообще лишний т.к. не выполняет своих функций... (никаких подобных мыслей в голову не пришло, когда в поток вставлял(пришлось , верю ;)  Application.ProcessMessages; ?)

по ошибке (вообше непонятно почему тебя волнует простая "пропажа" строк, у тебя же там AV через действие...)
нельзя работать через "два места", так открывать датасет перед открытием клиентского - ошибка. и исправлять в нем данные тоже. (расчет ключа (ID) )
в общем убери frmAskue.ADOQueryAllData.Open;, frmAskue.ADOQueryTestTable.Open; в коде и сабжевая ошибка пропадет (должна). но не остальные!!! по хорошему там единственный выход, переписать все нафиг.

по скорости... знаеш, так "затормозить" простые в общемто вещи, талант надо иметь... окрытие главной таблици, приходится ждать! (5-10 сек.) а всего то 2265 записей, простое открытие без "наворотов" в тестовой програмке составляет 0,01-0,02 сек. (???) и это сделано для ускорения вместо перезапросов? да пусть лучше перезапрашивает (хоть сто раз вместо одного, еще и "фора" остается).

p.s. а "EOF or BOF" ни разу не видел, хотя удалял полностью все записи и не раз... смена грида? перечитай [23] по этому поводу и присмотрись попристальнее к "своему" ххххEx гриду.


 
Shura ©   (2006-03-15 09:11) [26]


> ужас... код лучше любого фильма ужаса, что я видел

Ну бывает и хуже. Не все ж сразу спецами рождаются. Поэтому и вопросы задаются в форумах.


> в потоке единственный(!!!) валидный оператор (ExitProcess(0);
> ) все остальнее... ТАК ДЕЛАТЬ НЕЛЬЗЯ. поток вообще лишний
> т.к. не выполняет своих функций... (никаких подобных мыслей
> в голову не пришло, когда в поток вставлял(пришлось , верю
> ;)  Application.ProcessMessages; ?)

А можно пару аргументов почему ТАК делать нельзя. Поток выполняет одну единственную функцию открытие данные, не вешая программу, чтобы можно было прервать выполнение.


> по ошибке (вообше непонятно почему тебя волнует простая
> "пропажа" строк, у тебя же там AV через действие...)

Ни разу не случалось. А вот пропажа строк - это действительно проблема.


> нельзя работать через "два места", так открывать датасет
> перед открытием клиентского - ошибка. и исправлять в нем
> данные тоже. (расчет ключа (ID) )

ClientDataSet.Data:=DataSetProvider.Data
это правильное открытие ?
А вот насчет расчета ключа, тут пришлось делать именно так. Имеется ошибка в работе СУБД, признанная на их офф. сайте.


> по скорости... знаеш, так "затормозить" простые в общемто
> вещи, талант надо иметь... окрытие главной таблици, приходится
> ждать! (5-10 сек.) а всего то 2265 записей, простое открытие
> без "наворотов" в тестовой програмке составляет 0,01-0,02
> сек. (???) и это сделано для ускорения вместо перезапросов?
>  да пусть лучше перезапрашивает (хоть сто раз вместо одного,
>  еще и "фора" остается).

Конечно, я ж не буду в тестовом примере выкладывать реальную таблицу. Всего записей около 50 тыс., причем в базе хранятся не те длинные строки, которые были в тесте, а их кусочки, которые собираются во View (десяток key join"ов и union"ов). Выполнение на сервере около 10 сек. Ну а потом закачка этих строк в ClientDataSet и занимает основное время.


> p.s. а "EOF or BOF" ни разу не видел, хотя удалял полностью
> все записи и не раз... смена грида? перечитай [23] по этому
> поводу и присмотрись попристальнее к "своему" ххххEx гриду.
>

С "родным" Grid"ом наблюдается тоже самое. Да я на это уже забил.

P.S. Наш разговор не сочтут флеймом. Может лучше через почту ?


 
sniknik ©   (2006-03-15 11:14) [27]

> А можно пару аргументов почему ТАК делать нельзя.
аргумент один, из дополнительного потока недопустимо обращатся к обьектам VCL они "однопоточны" (только в главном). синхронизация как раз и делает "возврат" к основному, и выполнение кода в нем. но у тебя даже в вызовы синхронизации вставлены процедуры из VCL-евских обьектов, т.е. сначала идет обращение к ним а после оно пытается ее с основной синхронизировать (откуда только что "выдернула").

> ClientDataSet.Data:=DataSetProvider.Data
> это правильное открытие ?
не знаю. я бы так не делал. вообще копирование в принципе может быть и вполне нормальным по логике, но у тебя то там обмен, принятие обновлений делаеш, а так при копировании данных оно вроде работать не будет. (надо проверять)

> А вот насчет расчета ключа, тут пришлось делать именно так. Имеется ошибка в работе СУБД, признанная на их офф. сайте.
скрипты, процедуры, тригеры  СУБД поддерживает? навесь тригер пусть в самой базе расчитывается а не в программе. или добавление записи делать процедурой/скриптом в которой и расчитывать (опять в базе а не в программе)

> Ну а потом закачка этих строк в ClientDataSet и занимает основное время.
вот и зачем он тогда нужен? (см. выше. уже про это говорил)

> С "родным" Grid"ом наблюдается тоже самое.
в одном случае ошибка в возможна, когда изза рассинхронизации твоим кодом в адошном рекордсете уже не остается записей(/и достаточно одной такой), а в клиентском еще есть и их пытаются удалить. несуществующие, по несуществующему уже букмарку...  ошибка будет вполне оправдана, но возникнет не изза "глюка" ado, а изза твоего кода, и не при удалении всех записей а конкретной несуществующей. (о чем тоже вроде говорили).

> Да я на это уже забил.
вот это зря

> P.S. Наш разговор не сочтут флеймом. Может лучше через почту ?
с чего бы, если разговор по существу?
а через почту не общаюсь, я ее и проверяю обычно только раз в неделю, в субботу. исключения как в случае попросил чтото прислать конечно есть, но это только исключения. ("домашний" ящик на работе не подключен даже)

p.s. пробовал убрать то что я говорил? и кстати все "рефреши" клиентского рекордсета тоже, и работать только через него (все изменения) тогда и смысл рефреша пропадает.


 
Shura ©   (2006-03-15 12:42) [28]


> аргумент один, из дополнительного потока недопустимо обращатся
> к обьектам VCL они "однопоточны" (только в главном)...

Просто были ситуации, когда обновление компонента не проходило без Refresh"a.


> не знаю. я бы так не делал. вообще копирование в принципе
> может быть и вполне нормальным по логике, но у тебя то там
> обмен, принятие обновлений делаеш, а так при копировании
> данных оно вроде работать не будет. (надо проверять)

Как раз работает, тут проблем не было. В любом случае придется открывать и ADOQueryTestTable.Open, иначе нельзя выставить свойства ADO.


> скрипты, процедуры, тригеры  СУБД поддерживает? навесь тригер
> пусть в самой базе расчитывается а не в программе. или добавление
> записи делать процедурой/скриптом в которой и расчитывать
> (опять в базе а не в программе)

Глюк базы не в расчете ключа, а в значении, которое возвращает база по команде ADO: Select @@IDENTITY. В программе необходимо корректно обновить ключ, который и обновляется внутри ADO, туда я залезть не могу. Мне кажется в этой ситуации ни триггеры, ни процедуры не помогут.


> вот и зачем он тогда нужен? (см. выше. уже про это говорил)

Нужен он только для сортировки/фильтрации по расчетным полям. У меня ClientDataSet используется в качестве некоей Memory Table. Ну не умеет делать подобного ADO ! Есть стандартные компоненты, кроме ClientDataSet"а для таких функций ?


> в одном случае ошибка в возможна, когда изза рассинхронизации
> твоим кодом в адошном рекордсете уже не остается записей(/и
> достаточно одной такой), а в клиентском еще есть и их пытаются
> удалить. несуществующие, по несуществующему уже букмарку.
> ..  ошибка будет вполне оправдана, но возникнет не изза
> "глюка" ado, а изза твоего кода, и не при удалении всех
> записей а конкретной несуществующей. (о чем тоже вроде говорили).
>

Такая рассинхронизация возможна только если править сначала адошный рекордсет, а потом клиентский. У меня работа ведется ТОЛЬКО с клиентским. Удалил запись(и) - сделал ApplyUpdate. Как при этом записи в ADO могут исчезнуть раньше, чем в ClientDataSet"е ?


> p.s. пробовал убрать то что я говорил? и кстати все "рефреши"
> клиентского рекордсета тоже, и работать только через него
> (все изменения) тогда и смысл рефреша пропадает.

Частично. ADOQueryTestTable.Open остается см. выше. Если убрать Refresh, то вновь добавленные записи в ClientDataSet"е не фильтруются и не сортируются. Если работать только через ClienDataSet, то действительно "жить" будет проще. Но надо будет вручную обновлять значения ключей для добавленных записей, то что делает само ADO. Да и вообще, есть возможность ResolveToDataSet:=True, значит должно работать. А так все равно уходим от глюка своими средствами, но глюк остается.


 
sniknik ©   (2006-03-15 13:17) [29]

> Просто были ситуации, когда обновление компонента не проходило без Refresh"a.
это не повод делать из программы "мину случайного действия". избавляйся от ситуаций.

> Как раз работает, тут проблем не было. В любом случае придется открывать и ADOQueryTestTable.Open, иначе нельзя
> выставить свойства ADO.
но в этом открытии то и ошибка! (одна из...) а выставить можно в любом более менее подходяшем событии (afteropen к примеру)

> Глюк базы не в расчете ключа, а в значении, которое возвращает база по команде ADO: Select @@IDENTITY
и что в нем не так? выдает не то значение что нужно? значит в базе уже есть тригер и в нем есть вставки/апдейты которые его "сбивают", не можеш править (хотя это как раз проще всего) получай значение сам по IDENT_CURRENT (вернее аналогу, чего там в Sybase)

> Нужен он только для сортировки/фильтрации по расчетным полям. У меня ClientDataSet используется в качестве некоей
> Memory Table.
в том виде что я видел (расчетные поля в клиентском) по тому и он не отсортирует.
> Ну не умеет делать подобного ADO ! Есть стандартные компоненты, кроме ClientDataSet"а для таких функций ?
если ты чегото не знаеш это не значит что этого нет. я же говорил что умеет, и работает, и легко заменяет "Memory Table".

> Такая рассинхронизация возможна только если править сначала адошный рекордсет, а потом клиентский. ...
а также при "насильственном" заранее открытии адошного. его должен открывать провайдер данных.
ты пытаешся сделать "зеркало" адошного рекордсета в клиентском, но не учитывая их внутренней работы по обмену. в нормальном же режиме он "проходной" (нужен открыли получили данные, не нужен закрыли). в общем нельзя так.

> Частично. ADOQueryTestTable.Open остается см. выше. ...
убери. если оставляеш в этом виде.
а лучше переделай наоборот без клиентских.

> но глюк остается.
я бы не сказал что это глюк... вот если феррари в плуг вместо трактора впрячь, то будет ли "глюком"/недоработкой то, что кроме первого "отвала" земли она дальше не пашет, да и то с рывка? а помощьности вроде мотор даже сильнее тракторного...


 
Shura ©   (2006-03-15 15:24) [30]


> но в этом открытии то и ошибка! (одна из...) а выставить
> можно в любом более менее подходяшем событии (afteropen
> к примеру)

Ну да... Свойства выставляются для открытого ADOQuery, так что открывать придется, если через него работать.


> и что в нем не так? выдает не то значение что нужно? значит
> в базе уже есть тригер и в нем есть вставки/апдейты которые
> его "сбивают", не можеш править (хотя это как раз проще
> всего) получай значение сам по IDENT_CURRENT (вернее аналогу,
>  чего там в Sybase)
.
Выдает не то значение. Глюк такой: имеется 2 таблицы А и Б. На таблице А висит insert-триггер, который вставляет запись в таблицу Б. Так вот по команде ADO Select @@IDENTITY выдается значение автоинкремента не таблицы А, а таблицы Б. Других глобальных переменных в Sybase"е данной версии нет, аналогов тоже. Версия СУБД старая под realtime OS QNX 4.25. Обновление OS официально прекращено :-( С разработчиком уже переписывались.


> в том виде что я видел (расчетные поля в клиентском) по
> тому и он не отсортирует

Как раз таки сортирует. Там fkInternalCalc-поля - по ним возможна и сортировка (индексы) и фильтрация.


> если ты чегото не знаеш это не значит что этого нет. я же
> говорил что умеет, и работает, и легко заменяет "Memory
> Table".

Так я ж и спрашиваю, может мне подскажут аналог или код как сортировать/фильтровать в ADO. Вот сейчас пробую сделать:
ADODataSet1.Sort:="NameCalc ASC";
вылезает ошибка EOleException "Не удается найти объект в семействе, соответствующий требуемому имени или порядковому номеру", таже ошибка для
ADODataSet1.Filter:="NameCalc Like ""%F%""".
где поле NameCalc - fkCalculated.


> а также при "насильственном" заранее открытии адошного.
> его должен открывать провайдер данных.
> ты пытаешся сделать "зеркало" адошного рекордсета в клиентском,
>  но не учитывая их внутренней работы по обмену. в нормальном
> же режиме он "проходной" (нужен открыли получили данные,
>  не нужен закрыли). в общем нельзя так.

Да, действительно. В общем ОГРОМНОЕ СПАСИБО. Все остальное тоже заработало как надо. Если б не сорт./фильт. можно было бы отказаться от ClientDataSet"а :-))).


 
sniknik ©   (2006-03-15 16:09) [31]

> Ну да... Свойства выставляются для открытого ADOQuery, так что открывать придется, если через него работать.
НЕТ не придется. самому открывать НЕ НАДО, если пропишеш в событии то они установятся НЕЗАВИСИМО ОТ ТОГО КЕМ ОТКРЫТО.

> Как раз таки сортирует. Там fkInternalCalc-поля - по ним возможна и сортировка (индексы) и фильтрация.
>
> Так я ж и спрашиваю, может мне подскажут аналог ...
вообщето т спрашивал не это а то почему твое не работает.
сортировка
береш ADODataSet, с коннектом, гридом (чтобы видеть), ложиш НА ПУСТУЮ форму в новом приложении (исключить влияние твоего кода)
все настройки по умолчанию
запрос
ADODataSet1.CommandText:= "select *, 0 AS ForSort from Table1";
в добавленых полях у ForSort FieldKind ставиш fkCalculated
события
procedure TForm1.ADODataSet1CalcFields(DataSet: TDataSet);
begin //дествие для примера потом будет твое (id это автоинкремент, но в общем любое что у тебя есть можно)
 ADODataSet1ForSort.AsInteger:= 20 - ADODataSet1ID.AsInteger;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin //сортировка
 ADODataSet1.Sort:= "ForSort DESC"
end;

все.

можно еще добавить LockType = ltBatchOptimistic (исключить обновления базы) но и без этого должно работать. 100% не дам (много от провайдера зависит) но шанс большой.

от фильтраций лучше бы отказаться, лучше на клиента "гонять" только нужное но в принципе... для таких полей пойдет событие onfilterrecord.


 
Shura ©   (2006-03-15 16:31) [32]


> sniknik

Сортировка сработала, а вот фильтр нет. Может я чего еще не доглядел. Все равно спасибо еще раз.


 
sniknik ©   (2006-03-15 16:34) [33]

Shura ©   (15.03.06 16:31) [32]
> а вот фильтр нет. Может я чего еще не доглядел.
sniknik ©   (15.03.06 16:09) [31]
> .... для таких полей пойдет событие onfilterrecord.


 
Shura ©   (2006-03-15 16:37) [34]

Фишка, наверное в том, чтобы Recordset содержал "заготовки" для сортировочных полей, а если их создавать в DataSet"е, то сортировка не прокатит.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.62 MB
Время: 0.013 c
2-1145633091
mahab
2006-04-21 19:24
2006.05.07
DVD-RW


3-1142226823
Chel
2006-03-13 08:13
2006.05.07
Поиск в списочных компонентах


3-1142329116
hursand
2006-03-14 12:38
2006.05.07
текcтавом формате


1-1143718105
Max Zyuzin
2006-03-30 15:28
2006.05.07
Обработка в сервисе по системному времени


15-1144877931
Volf_555
2006-04-13 01:38
2006.05.07
Как в Internet Explorer отображать php-скрипты?!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский