Формирование выборки в AVI#

Способы формирования результата выборки#

Изначально результат выборки формируется операцией onRefresh или onRefreshItem одним из двух способов: реляционный или объектный запрос.

Реляционный запрос#

В теле onRefresh вызывается метод selectStatement или prepareSelectStatement (вызывает тот же selectStatement, но с добавлением фильтров, описанных в avm).
Результатом операции onRefresh является текстовое значение, внутри которого реляционный запрос.

Примечание

onRefreshExt в случае формирования выборки реляционным запросом не вызывается.

Так формируется по умолчанию отображение List (кроме коллекций).
Не учитываются значения хранящиеся в кэше, учитываются значения только из БД.

Пример selectStatement для отображения List:

override protected def selectStatement: String = {
  s"""SELECT
    t.id  
    ,t.idClass  
    ,t.idState  
    ,t1.sHeadLine_dz as idStateHL  
    ,t.idStateMC  
    ,t.idObjectType  
    ,t2.sHeadLine_dz as idObjectTypeHL  
    ,t.idDepOwner  
    ,t3.sHeadLine_dz as idDepOwnerHL  
    ,t.gidSrc  
    ,t.idResourceHolder  
    ,t4.sHeadLine_dz as idResourceHolderHL  
    ,t.sRegNum  
    ,t.dReg  
    ,t.idPeriod  
    ,t5.sHeadLine_dz as idPeriodHL  
    ,t.sDescription  
    ,t.gid  
    ,t.sRegNum_dz  
    ,t.sRegNumBMs_dz  
    ,t.sRegNumidVer_dz  
    FROM Oil_DemandMov t
      LEFT JOIN  Btk_ClassState t1 on t.idState = t1.id
      LEFT JOIN  Btk_ObjectType t2 on t.idObjectType = t2.id
      LEFT JOIN  Bs_DepOwner t3 on t.idDepOwner = t3.id
      LEFT JOIN  Bs_Contras t4 on t.idResourceHolder = t4.id
      LEFT JOIN  Bs_Period t5 on t.idPeriod = t5.id
  """
}

Коммит в БД при выполнении реляционного запроса и @FlushBefore#

При реляционном запросе сервер приложения делает коммит в БД (особенность работы сервера приложения). Поэтому на выборках, где вводятся значения в поля и поддерживается возможность пользователю отменить изменения, нельзя использовать формирование выборки на реляционном запросе. Иначе данные запишутся в БД без разрешения пользователя (без нажатия пользователем на операцию сохранения (дискетка)).

Если есть необходимость в выполнении выборки на реляционном запросе в отображении с редактированием полей, то необходимо добавить перед onRefresh аннотоцию @FlushBefore(mode = FlushBeforeMode.Disabled).
Например, выборка выпадающего списка Lookup:

trait Lookup extends Default with super.Lookup {

  @FlushBefore(mode = FlushBeforeMode.Disabled)
  override protected def onRefresh: Recs = {
    s"""SELECT
        t.id
        ,t.sHeadLine_dz as sHeadLine
        ,t.sMnemoCode_dz as sMnemoCode
        ,coalesce(t.sMnemoCode_dz, '') || ' ' || coalesce(t.sHeadLine_dz, '') as sMnemoCodeHeadLine
      from AsfEqp_IntoOperExt t
      order by upper(t.sHeadLine_dz)
    """
  }
}

Иначе при открытии выпадающего списка данные будут записываться в БД.

Объектный запрос#

onRefresh формируется из экземпляров объектов SRop (инструменты refreshByParent, load, TxIndex, OQuery) или case class’ов.

Учитываются значения, хранящиеся в кэше.

Примеры:

  • По умолчанию отображение List у коллекций формируется с помощью refreshByParent:

trait List_idPlanFactoryShip extends Default with super.List_Master {

  override protected def onRefresh: Recs = {
    Oil_PlanFactShipSegrGroupApi().refreshByParent(getIdMaster)
  }
}
  • По умолчанию отображение Card у коллекций формируется с помощью load:

trait Card extends Default with super.Card {

  override protected def onRefreshItem: Recs = {
    Oil_PlanFactShipSegrGroupApi().load(getVar(getPKFieldName).asNLong)
  }
}

Расширение объектной выборки вычисляемыми полями#

В случае объектного запроса сервер сам вызывает метод onRefreshExt, в который можно дописать получение нехранимых полей на синтаксисе SQL, НЕ учитывая значения из кэша:

override protected def onRefreshExt: String = {
  s"""with t as ( select 
   :id as id
  ,:idPlanFactoryShip as idPlanFactoryShip
  ,:idSegregationGroup as idSegregationGroup
)
SELECT
   t.id
  ,t1.sHeadLine_dz as idPlanFactoryShipHL
  ,t2.sHeadLine_dz as idSegregationGroupHL
  ,t2.sMnemoCode_dz as idSegregationGroupMC
FROM t
  LEFT JOIN  Oil_PlanFactoryShip t1 on t.idPlanFactoryShip = t1.id
  LEFT JOIN  Oil_SegregationGroup t2 on t.idSegregationGroup = t2.id
"""
}

Примечание

Также существует другой способ реализовать нехранимые поля (через case class AdditionalInfo), который будет описан дальше. Данный способ формирует значения с учётом кэша.