Введение в SQL Server Analysis Services для разработчика. Метод Discover

Содержание предыдущей серии.

Вторым из двух методов XMLA является Discover. Discover позволяет запрашивать различные метаданные Analysis Services: параметры инстанса, базы данных в инстансе, кубы в базе данных и т.д., а также открытые сессии, транзакции, блокировки и т.д., заканчивая активными трассами мониторинга и зарегистрированными счетчиками производительности для Analysis Services у целом. Результат возвращается в виде реляционной таблицы, ну то есть в данном случае мы его будем видеть в виде XML, но идейно это таблица, а не CellSet, поэтому результаты метода Discover называются еще схемными роусетами (Schema Rowsets). Пример: обнаруживаем все БД, проживающие на текущем экземпляре SSAS:

<Discover xmlns="urn:schemas-microsoft-com:xml-analysis"> 
  <RequestType>DBSCHEMA_CATALOGS</RequestType> 
  <Restrictions /> 
  <Properties /> 
</Discover>

Скрипт 1

Рис. 1

Как и в случае с Execute, надлежащая SOAP-обертка пристегивается автоматически. Т.е. Скрипт 1 можно было явно обернуть в полную форму в виде:

<soap:Envelope xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/"> 
  <soap:Body> 
    <Discover xmlns="urn:schemas-microsoft-com:xml-analysis"> 
      <RequestType>DBSCHEMA_CATALOGS</RequestType> 
      <Restrictions /> 
      <Properties /> 
    </Discover> 
  </soap:Body> 
</soap:Envelope>

Скрипт 2

и он бы также успешно выполнился с ровно тем же результатом с точностью до внешних скобок

<soap:Envelope ...>

<soap:Body>

<DiscoverResponse ...>

Рис. 2

но зачем писать лишние элементы с soap, если AS это cделает за нас.

Результатом является традиционно XML. Традиционно в начале идет всякая XSD-ботва, потом в элементах <row> появляется осмысленная информация.

Синтаксис метода Discover приводится в BOL здесь. Он очень простой и похож на Execute. Вместо Command здесь служит RequestType – что, собственно, будем дискаверить. Вместо Parameters – Restrictions. Как написано в спецификации XMLA 1.1, Restrictions, the parameter of the Restrictions data type, enables the user to restrict the data returned in Result. Определение в армейском стиле: боевой листок должен быть боевым листком, ведь это же боевой листок. Properties остаются те же самые, что и в методе Execute. Их можно посмотреть в BOL, а можно при помощи метода Discovery. Прямо рекурсия какая-то получается: для приготовления салата возьмите 100 г салата... Ну не суть. Вот, что я имел в виду:

<Discover xmlns="urn:schemas-microsoft-com:xml-analysis"> 
  <RequestType>DISCOVER_PROPERTIES</RequestType> 
  <Restrictions /> 
  <Properties /> 
</Discover>

Скрипт 3

Рис. 3

Мы видим, что метод DISCOVER настолько любезен, что позволяет обнаруживать свои собственные компоненты. Только не путайте, пожалуйста, риквест тайп DISCOVER_PROPERTIES с риквест тайпом MDSCHEMA_PROPERTIES. Первый выдает полный список XMLA-cвойств. Список значений элемента <PropertyName> в выдаче – это то, что, в принципе, может выступать в качестве элемента внутри элемента <PropertyList> внутри элемента <Properties> в XMLA-запросе. Например, в выдаче Скрипта 3 есть PropertyName = Format, что означает, что XMLA понимает такое свойство внутри запроса (см., напр., пред.серию, Рис.1). Второй относится к свойствам вычисляемого члена или ячейки в MDX-запросе, т.е. то, что выдается предикатом DIMENSION PROPERTIES или CELL PROPERTIES оператора SELECT. Кстати говоря, при помощи метода Discover можно посмотреть не только список доступных Properties, какие в нем можно использовать, но и собственно RequestTypes:

<Discover xmlns="urn:schemas-microsoft-com:xml-analysis"> 
  <RequestType>DISCOVER_SCHEMA_ROWSETS</RequestType> 
  <Restrictions/> 
  <Properties/> 
</Discover>

Скрипт 4

Рис. 4

Все, что мы видим внутри элементов <SchemaName>, может использоваться в качестве RequestType метода Discover. В отличие от DISCOVER_PROPERTIES не предусмотрено риквест тайпа DISCOVER_RESTRICTIONS, однако если мы посмотрим на Рис.4, то увидим, что каждый риквест тайп (SchemaName) перечисляется вместе с ограничениями, которые к нему можно применять. Так, например, можно видеть, что к MDSCHEMA_CUBES можно применять ограничение CATALOG_NAME, которое позволяет вытаскивать кубики из конкретной базы. Вместе с тем, существует также свойство по имени Catalog, которое занимается тем же и которое мы использовали, например, еще в самом первом посте этой серии \ Скрипт 1. (Помним, что набор Properties, которые могут использоваться в запросах EXECUTE и DISCOVER, один и тот же). Вот я и подумал, а что будет, когда в запросе DISCOVER ограничение CATALOG_NAME в риквест тайпе MDSCHEMA_CUBES не совпадет со значением свойства Catalog в элементе Properties того же запроса? Я поискал ответ в BOL и спецификации XMLA 1.1 и не нашел. Во всех примерах, где эти два элемента используются в запросе одновременно, они одинаковы, хотя нигде не написано, что нельзя, например, в ограничениях указать одну базу, а в свойствах другую. Тогда я решил проверить на практике.

<RequestType>MDSCHEMA_CUBES</RequestType> 
  <Restrictions> 
    <RestrictionList> 
      <CATALOG_NAME>Adventure Works DW 2008R2</CATALOG_NAME> 
    </RestrictionList> 
  </Restrictions> 
  <Properties> 
    <PropertyList> 
      <Catalog>Test</Catalog> 
    </PropertyList> 
  </Properties> 
</Discover>

Скрипт 5

Ни в коем случае не пытайтесь повторить этот запрос самостоятельно: в ходе его выполнения Analysis Services никак не может решить, кубы из какой базы показывать, из-за чего процессор сильно греется и в конце концов сгорает. «Протянет все ноги процессор, замкнутся дорожки на плате, на мышку сквозь щель дисковода польется кипящий металл...» (с).

Шутка. XMLA красив, строен, целостен и логически непогрешим, что позволило данному стандарту продержаться более 7 лет практически без изменений. Впрочем, в этом реверансе я уже расшаркивался где-то в начале сериала.

Рис. 5

По всей вероятности, вначале выполняется запрос с учетом Properties, из которого затем отфильтровываются результаты, не удовлетворяющие Restrictions. Таким образом, Скрипт 5 возвратит пустоту, в смысле 0 элементов <row>.

Переход на следующую серию.

Автор: Алексей Шуленин