Архитектура BDE и его особенности при работе с SQL-серверами - TTable и TQuery
ОГЛАВЛЕНИЕ
TTable и TQuery
TTable и TQuery являются основными компонентами, используемыми при программировании приложений баз данных (TStoredProc не в счет, и без него можно прекрасно обойтись, вызывая процедуры через select или execute в компоненте TQuery). TTable предоставляет доступ как к таблицам, а TQuery позволяет выполнять произвольные запросы. Если с TQuery все понятно - он выполняет тот запрос, который написан в свойстве TQuery.SQL - то TTable скрывает очень много подробностей своей работы от программиста. Без SQL Monitor увидеть все тонкости невозможно (если кто не знает - SQL Monitor находится в меню Database).
Итак, запустите Delphi, откройте SQL Monitor, положите на форму компонент TDatabase, подсоединитесь к серверу, затем положите компонент TTable, присоедините его к алиасу TDatabase и выберите любую таблицу из списка (свойство TableName). Переключитесь на SQL Monitor, сотрите все что там появилось, переключитесь обратно, и включите TTable.Active:=True; Смотрим в SQL Monitor (лог с самого начала):
- первым запросом BDE хочет убедиться, что выбранная нами таблица существует.
- второй запрос выбирает список полей выбранной таблицы, их названий, типов, условий проверки и т.п.
- третий запрос выбирает информацию об индексах указанной таблицы. Определяется, есть ли среди них первичный ключ, и по каким полям построены индексы.
- четвертый запрос почти повторяет второй, и выбирает информацию о полях - условия проверки, "вычисляемость" поля, допустимость NULL и прочее.
- собственно, пятый запрос открывает таблицу, формируя запрос SELECT FIELD1, FIELD2, ... FROM TABLE ORDER BY PK_FIELD ASC.
Заметьте, что подобные запросы выполняются каждый раз при открытии таблицы (любой) компонентом TTable. Перечитывания этих данных можно избежать, если включить у используемого алиаса параметр ENABLE SCHEMA CACHE. При этом считанную первый раз информацию BDE размещает на диске в указанном каталоге (SCHEMA CACHE DIR) в специальном файле, кэширует информацию для SCHEMA CACHE SIZE количества таблиц, и держит эту информацию в кэше в течение SCHEMA CACHE TIME секунд (если -1, то вечно). Если структуры таблиц закэшированы, то при их изменении на сервере (например, добавили новое поле) приложение будет работать со старой структурой, что может вызвать серьезные проблемы в работе приложения. SCHEMA CACHE нужно использовать только тогда, когда структура базы данных определена окончательно и не изменяется. Если все же очень сильно хочется использовать кэширование структур таблиц, то не забывайте правильно установить параметр SCHEMA CACHE TIME. Или при первом за день подключении приложения к серверу сначала кэширование структур можно выключить, отсоединиться, включить и подсоединиться снова - таким образом в самом начале работы кэш структур таблиц будет создан, и будет использоваться в течение дня.
примечание:
параметры SCHEMA CACHE не имеют абсолютно никакого отношения к механизму Cached Updates или к кэшированию данных.
Вернемся к запросу, которым TTable открыл таблицу. В конце запроса стоит указание порядка сортирвки - ORDER BY FIELD ASC. По умолчанию TTable сортирует данные в порядке поля первичного ключа. И кстати, если пользоваться свойством TTable.IndexName, то все равно к запросу будет добавляться ORDER BY INDEXFIELD ASC. Таким образом получается, что свойство IndexName при работе с SQL-серверами бессмыслено. Вместо него нужно просто использовать свойство IndexFieldNames. Даже если в этом свойстве указать поле, по которому нет индекса, то все равно BDE "прицепит" к запросу ORDER BY FIELD ASC. Кстати, BDE абсолютно игнорирует направление индекса, и всегда в запросе добавляет ASC, даже если индекс по этому полю создан как DESCENDING (по убыванию). Получается, что отсортировать таблицу в TTable по убыванию нельзя.
примечание:
можно было бы отнести этот недостаток на SQL Link для IB, но вполне возможно что просто TTable не в состоянии кэшировать и обновлять данные, отсортированные по убыванию (см. дальше о кэше данных).