Существует два типа фильтров:

  • SyncFilter - позволяет ограничить передаваемые пользователю данные. В результате работы фильтра, в базе данных пользователя будут  только те данные, которые ему необходимы, и к которым он имеет доступ.Это крайне актуально для мобильных приложений, работающих на не самом быстром оборудовании и при низкой пропускной способности сети.
  • DeleteFilter - позволяет удалять данные из базы данных мобильного приложения, которые уже не являются актуальными. Все данные, попадающие под фильтр будут удалены из таблицы на мобильном устройстве после синхронизации с сервером.

Фильтры являются частью объектной модели решения (файла метаданных).

Синтаксис

Значение фильтра необходимо присвоить атрибуту SyncFilter(DeleteFilter) объекта, на который он накладывается, и(или) его табличной части(частей). Если фильтр задан для табличной части и основного объекта - сервер применит оба. 

Фильтр представляет собой SQL выражение, следующее после условия WHERE.

При формировании фильтра DeleteFilter необходимо обрамлять имя схемы таблицы нижними подчеркиваниями (например _Catalog_Entity вместо Catalog.Entity)


Фильтр выполнятся в контексте, в котором:

  • псевдоним "Т" ссылается на таблицу, к которой применяется условие
  • переменная @UserId содержит идентификатор текущего пользователя.

Например:

SyncFilter
T.SR = @UserId AND T.PlanStartDataTime > (GETDATE() - 10) // записи текущего пользователя с датой не старше 10 дней


DeleteFilter
_Catalog_Accounts.Description='12345'//записи со значением '12345' в поле Description


In-фильтры  в атрибуте SyncFilter

В случае необходимости использования вложенных запросов следует использовать оператор IN.

Сервер GROTEM  допускает только один "внешний" оператор IN в выражении, например:

T.Owner IN (SELECT Id FROM Catalog.SKUGroup WHERE Manager  = @UserId)

Выражения вида T.Owner IN (SELECT Id FROM Catalog.SKUGroup WHERE Manager  = @UserId) AND T.PlanStartDataTime > (GETDATE() - 10) недопустимы. Всю сложную логику следует помещать в скобках - там ограничений нет, например:

T.Id IN (SELECT Id FROM Catalog.SKU WHERE Owner IN (SELECT Id FROM Catalog.SKUGroup WHERE Manager  = @UserId) AND T.PlanStartDataTime > (GETDATE() - 10))

Выражение IN допустимо только по отношению к полю ссылочного типа.

Принцип работы

Простые (не IN-фильтры) применяются при синхронизации мобильного агента в момент определения сервером, какие записи следует возвратить. При этом если синхронизация не первая, и выборка изменилась с момента последней синхронизации (например условие фильтра включает в себя текущую дату) - "старые" записи останутся в базе данных устройства, хотя формально под условие фильтра они уже не попадают.

Для решения данной проблемы, и более сложных случаев, когда, например, выборка зависит от набора записей в других таблицах (нужно вернуть торговые точки добавленные в территории текущего торгового представителя), следует использовать In-фильтры, которые сервер GROTEM  отрабатывает по более сложному сценарию:

  • Для каждого объекта с In-фильтром при выгрузке метаданных сервер создает таблицу ИмяОбъекта_filterids
  • В начале сеанса синхронизации мобильного агента сервер вычисляет выражение фильтра и помещает идентификаторы в таблицу filterids:
    Идентификаторы, отсутствующие в таблице, помечаются как "новые".
    Идентификаторы, присутствующие в таблице, но отсутствующие в выборке, помечаются как "удаленные".
  • Используя статусы записей, сервер возвращает мобильному агенту новые записи и информацию о том, какие записи следует удалить.
  • Таблицы filterids очищаются при первичной синхронизации мобильного агента (и очистке кеша).

Рекомендации

  • Не рекомендуется использовать псевдонимы таблиц, оканчивающиеся на Т
  • Названия полей желательно обертывать в квадратные скобки [], чтобы избегать конфликтов с ключевыми словами MS SQL Server (например T.[User] вместо T.User)
  • При использовании In-фильтров следует помнить, что сервер хранит идентификаторы объектов в таблицах filterids для каждого пользователя. Поэтому следует быть "аккуратнее в выражениях", желательно чтобы фильтр возвращал минимум записей. Например:
    Если необходимо отфильтровать справочник товаров (Catalog.SKU) по группе номенклатуры (Catalog.SKUGroup), можно использовать выражения:
     T.Id IN (SELECT Id FROM Catalog.SKU S JOIN Catalog.SKUGroup SG ON S.Owner = SG.Id WHERE SG.Manager = @UserId)
     T.Owner IN (SELECT Id FROM Catalog.SKUGroup WHERE SG.Manager = @UserId)
    В первом варианте в таблицу filterids будут помещены идентификаторы товаров, которых может быть на порядки больше чем идентификаторов групп второго выражения. Что приведет к дополнительной нагрузке на сервер.
  • Нет меток
Написать комментарий...