IBTable - сортировка DESC
Такая вот проблема.. нужно реализовать сортировку в обратном порядке (DESC), знаю как, но возникают какие-то глюки.
Есть IBTable (НЕ Query - ORDER BY не предлагать!) привязанный к таблице под FireBird 1.5.
При нажатии на заголовок колонки грида делаю следующее:
table.DeleteIndex('sort_index');
table.AddIndex('sort_index',Column.Field.FieldName,[ixDescending]);
table.IndexName := 'sort_index';
В примерах на эту тему видел, что перед этими действиями закрывают датасет, а после снова открывают - пробовал и так тоже - эффект один (зачем тогда его закрывать, если и с откртым он нужные св-ва получает?). Вобщем приведенный пример сортирует как надо только один раз - если в OnShow формы пишу table.IndexName := 'sort_index';
При нажатии на другие колонки - т.е. смене поля в индексе, сортировка по новому полю уже не происходит - ни ASC, ни DESC
Пробовал вместо
table.IndexName := 'sort_index';
писать
table.IndexFieldNames := Column.Field.FieldName;
Такой вариант почему-то вообще не обращает внимания на то, что индекс DESC, но зато при каждом нажатии на любую колонку - сортировка (ASC) успешно отрабатывает.
Я что-то неправильно понял? Delphi у меня 6ая.. в поисковике наткнулся на заявление некоторого буржуйского господина о том, что IBTable у него неправильно сортировал индексы из нескольких полей - он там иходних компоненты вправил, но это не мой случай - у меня индекс по одному полю, да и я думаю дело в чем-то другом.
Здравствуйте,
Такая вот проблема.. нужно реализовать сортировку в обратном порядке (DESC), знаю как, но возникают какие-то глюки.
Есть IBTable (НЕ Query - ORDER BY не предлагать!) привязанный к таблице под FireBird 1.5.
При нажатии на заголовок колонки грида делаю следующее:
table.DeleteIndex('sort_index');
table.AddIndex('sort_index',Column.Field.FieldName,[ixDescending]);
table.IndexName := 'sort_index';
В примерах на эту тему видел, что перед этими действиями закрывают датасет, а после снова открывают - пробовал и так тоже - эффект один (зачем тогда его закрывать, если и с откртым он нужные св-ва получает?). Вобщем приведенный пример сортирует как надо только один раз - если в OnShow формы пишу table.IndexName := 'sort_index';
При нажатии на другие колонки - т.е. смене поля в индексе, сортировка по новому полю уже не происходит - ни ASC, ни DESC
Пробовал вместо
table.IndexName := 'sort_index';
писать
table.IndexFieldNames := Column.Field.FieldName;
Такой вариант почему-то вообще не обращает внимания на то, что индекс DESC, но зато при каждом нажатии на любую колонку - сортировка (ASC) успешно отрабатывает.
Я что-то неправильно понял? Delphi у меня 6ая.. в поисковике наткнулся на заявление некоторого буржуйского господина о том, что IBTable у него неправильно сортировал индексы из нескольких полей - он там иходних компоненты вправил, но это не мой случай - у меня индекс по одному полю, да и я думаю дело в чем-то другом.
Выходит по-твоему лучше создать индекс, вызвать sort DESC , потом его удалить, Чем ORDER BY в Query ? Если думаешь, что траффик станет меньше, то ошибаешься. Для его уменьшения нужно использовать ClientDataSet. Всякий раз, когда начинаю использовать IBTable дело заканчивается тем, что глубоко раскаиваюсь..
Полезность переоткрытия DataSet - в возможности увидеть то, что наваяли коллеги в базе пока сам созерцаешь предыдущий DataSet.
Выходит по-твоему лучше создать индекс, вызвать sort DESC , потом его удалить, Чем ORDER BY в Query ? Если думаешь, что траффик станет меньше, то ошибаешься. Для его уменьшения нужно использовать ClientDataSet. Всякий раз, когда начинаю использовать IBTable дело заканчивается тем, что глубоко раскаиваюсь..
Полезность переоткрытия DataSet - в возможности увидеть то, что наваяли коллеги в базе пока сам созерцаешь предыдущий DataSet.
Я вовсе не недооцениваю Query, тем более что c SQL'ом у меня все в порядке. Просто хочу разобраться.
Если уж с индексами так все запущено, не могли бы вы вкратце объяснить разницу TIBClientDataSet'а (да и не только IB) от не ClientDataSet'а, или может быть дать ссылку на статью, где это объясняется?
Пробовал его использовать - все получается, только странно как-то задается источник данных - как я понял в CommandText запросом - я писал SELECT * FROM MyTable; Так и надо?
Я вовсе не недооцениваю Query, тем более что c SQL'ом у меня все в порядке. Просто хочу разобраться.
Если уж с индексами так все запущено, не могли бы вы вкратце объяснить разницу TIBClientDataSet'а (да и не только IB) от не ClientDataSet'а, или может быть дать ссылку на статью, где это объясняется?
Пробовал его использовать - все получается, только странно как-то задается источник данных - как я понял в CommandText запросом - я писал SELECT * FROM MyTable; Так и надо?
статья про ClientDataSet
А вообще если применяешь Grid сторонних разработчиков, то всё равно они сами сортируют и тащут данные по сетке без нашего ведома. И зачастую удобство и скорость разработки становятся определяющими критериями (если конечно скорость обработки не критична для конкретной задачи).
Можно еще вопрос..
Установил IBX Update 6.08 для Delphi 6, перед установкой сказано:
IBXpress60.bpl is now ibxpress62.bpl due to interface
changes. Any package that depends on ibxpress.dcp
will require recompiling after installing this update.
You will get an error message that a function is missing
and do you wish to load this package later. Answer Yes
to this (you will get it twice) and then rebuild the
package. Answering no placed the package into a special
location in the registry and you can never have it
load on startup again without manually modifying
the registry.
Как сказано - так и происходит. Проблема в том, что я не пойму что, где и как нужно recompile'ить. Подскажите пожалуйста.
Спасибо, почитал.. решил на IBDataSet остановится - в нем все хорошо, вот только бы еще подставлял бы он Filter себе сам в запрос, а то у него этого свойства вообще нет - приходится вручную запрос менять.
Можно еще вопрос..
Установил IBX Update 6.08 для Delphi 6, перед установкой сказано:
IBXpress60.bpl is now ibxpress62.bpl due to interface
changes. Any package that depends on ibxpress.dcp
will require recompiling after installing this update.
You will get an error message that a function is missing
and do you wish to load this package later. Answer Yes
to this (you will get it twice) and then rebuild the
package. Answering no placed the package into a special
location in the registry and you can never have it
load on startup again without manually modifying
the registry.
Как сказано - так и происходит. Проблема в том, что я не пойму что, где и как нужно recompile'ить. Подскажите пожалуйста.
Sorry for terrible english. My native language is C++ :)
Не знаю как в Delphi , я на Builder работаю. А вообще зачем фильтр использовать ? По-моему Table делает тожк что Query т.е. строит запрос. Вообще генерация запросов, составление их самостоятельно процесс более естественный IMHO . Этот навык пригождается со временем, например при программировании на Perl&PHP, использовании XML&XSLT .
кроме того тейбл тянет все данные с сервера, а кверя - только часть курсора... национальный ты наш С++ Builder - базарюка :)))
DetailTable.Filter := 'ID_FK = ' + MasterTable.FieldByName('ID_PK');
Чем это не вариант и дольше ли это работает? По сложности (простоте) создания в среде разработке Master/Detail отношений вроде одинаково.
Интерестно как Master/Detail, указанный в среде разработки, может ускорить работу? Я не спорю с этим утверждением, просто мне интерестно. Я, к примеру, ни разу не настраивал в среде разработки Master/Detail - если нужно отобрать соответствующие ключу master-таблицы записи, я делаю
DetailTable.Filter := 'ID_FK = ' + MasterTable.FieldByName('ID_PK');
Чем это не вариант и дольше ли это работает? По сложности (простоте) создания в среде разработке Master/Detail отношений вроде одинаково.
Любi друзi! :)
конечно же не быстрее.
Пока сервер не отдаст - Delphi не покажет.
А запросы у Table & Query одинаковые.
Вот как работает IBTable (результат из под отладчика) :
connect for :op_attach
CONNECT_VERSION : 2
Architecture: arch_intel_32
DataBase: E:\Programming\MyProjects\Win\Navigator\Base\RIELTOR.GDB
Protocol to try: 2
op_attach
DataBase: E:\Programming\MyProjects\Win\Navigator\Base\RIELTOR.GDB
DPB: user_name=sysdba;password_enc=QP3LMZ/MJh.;dummy_packet_interval=0;working_directory=;
op_info_database
DBHandle: 0
incarnation: 0
Items: isc_info_db_sql_dialect;
buffer_length: 512
op_transaction
DBHandle: 0
Items:
op_transaction
DBHandle: 0
Items:
op_allocate_statement
DBHandle: 0
op_prepare_statement
TRHandle: 2
STHandle: 3
Dialect :3
SQL: Select R.RDB$FIELD_NAME, R.RDB$FIELD_POSITION,
F.RDB$COMPUTED_BLR, R.RDB$DEFAULT_VALUE, R.RDB$NULL_FLAG,
F.RDB$FIELD_LENGTH, F.RDB$FIELD_SCALE, F.RDB$FIELD_TYPE, F.RDB$FIELD_SUB_TYPE,
F.RDB$EXTERNAL_LENGTH, F.RDB$EXTERNAL_SCALE, F.RDB$EXTERNAL_TYPE
from RDB$RELATION_FIELDS R, RDB$FIELDS F
where R.RDB$RELATION_NAME = 'BALCONY'
and R.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME
order by R.RDB$FIELD_POSITION
Здесь таблица имеет фильтр и переключает индекс(WHERE & ORDER BY).
т.е. нужно заранее оптимизировать базу, индексы где нужно. И тогда Table & Query можно будет юзать по вкусу.
статья про ClientDataSet
В данной статье по IBTable сказано, что "Явно сортировку записей в обратном порядке (DESC) указать невозможно". А как неявно? Я так понимаю проблема в том, чтобы перехватить сгенерированный IBTable'ом SQL-запрос и добавить в него после нужных полей списка ORDER BY слово 'DESC'. Это реально сделать? Или можно хотя бы посмотреть текст сгенерированного IBTable'ом запроса, без его изменения?
Добавить 'DESC' в IndexFieldNames не получается, ругается что поле 'MyField DESC' не существует. Как его заставить думать, что то, что находится после пробела, это уже не имя поля?
Для связи Master/Detail в кверях можно использовать свойство DataSource (ссылка на мастер-TDataSource) у подчиненных запросов. В детэйл-кверях пишется в секции where что-то типа следующего: "where parent_id = :id". -где parent_id - поле ссылающееся на запись в главной таблице, а :id - поле первичного ключа у главной квери...
Так вот такой способ связи работает гораздо быстрее чем через MasterSource и т.д.
А насчет плана запроса, -х.з. как на самом деле отличается реализация IBTable от IBQuery (не смотрел и честно говоря нет желания) в плане скорости формирования и отправки запроса на сервер. А вообще есть смысл использовать IB-компоненты сторонних разработчиков...