Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Pós-Graduação em Ciência da Computação
“UMA ANÁLISE COMPARATIVA DE FUNÇÕES
MDX NOS SERVIDORES ANALYSIS SERVICES E
MONDRIAN”
Por
ERIVAM ANSELMO DE ALBUQUERQUE
Dissertação de Mestrado Profissional
Universidade Federal de Pernambuco
[email protected] www.cin.ufpe.br/~posgraduacao
RECIFE, ABRIL/2013
Universidade Federal de Pernambuco
CENTRO DE INFORMÁTICA
PÓS-GRADUAÇÃO EM CIÊNCIA DA COMPUTAÇÃO
Erivam Anselmo de Albuquerque
“Uma análise comparativa de funções MDX nos
servidores Analysis Services e Mondrian"
ORIENTADOR(A): Prof. Dr. Robson do Nascimento Fidalgo
RECIFE, ABRIL/2013
Este trabalho foi apresentado à Pós-Graduação em Ciência da
Computação do Centro de Informática da Universidade Federal de
Pernambuco como requisito parcial para obtenção do grau de Mestre
Profissional em Ciência da Computação.
Catalogação na fonte
Bibliotecária Jane Souto Maior, CRB4-571
Albuquerque, Erivam Anselmo de Uma análise comparativa de funções MDX nos servidores Analysis Services e Mondrian/ Erivam Anselmo de Albuquerque. - Recife: O Autor, 2013. xiii, 105 f. : il., fig.,gráf., quadro Orientador: Robson do Nascimento Fidalgo.
Dissertação (mestrado profissional) - Universidade Federal de Pernambuco. CIn, Ciência da Computação, 2013.
Inclui bibliografia, anexo e apêndice. 1. Banco de dados. 2. OLAP. I. Fidalgo, Robson do Nascimento (orientador). II. Título. 025.04 CDD (23. ed.) MEI2013 – 087
Dissertação de Mestrado Profissional apresentada por Erivam Anselmo de Albuquerque à Pós-Graduação em Ciência da Computação do Centro de Informática da Universidade Federal de Pernambuco, sob o título, “Uma Análise Comparativa de Funções MDX nos servidores Analysis Services e Mondrian”, orientada pelo Professor Robson do Nascimento Fidalgo e aprovada pela Banca Examinadora formada pelos professores:
_____________________________________________
Profª. Bernadette Farias Lóscio
Centro de Informática / UFPE
_____________________________________________
Profª. Maria da Conceição Moraes Batista Universidade Federal Rural de Pernambuco
_____________________________________________
Prof. Robson do Nascimento Fidalgo Centro de Informática / UFPE
Visto e permitida a impressão.
Recife, 22 de abril de 2013.
___________________________________________________
Profª. EDNA NATIVIDADE DA SILVA BARROS
Coordenadora da Pós-Graduação em Ciência da Computação do
Centro de Informática da Universidade Federal de Pernambuco.
iii
Dedico esta dissertação a Deus e a
minha família.
iv
AGRADECIMENTOS
Meus agradecimentos, em primeiro lugar, são direcionados a Deus, pela
vida, pela saúde, pela inspiração e por mais essa oportunidade que me
proporcionou. A Ele toda a glória.
Agradeço especialmente a minha família, nas pessoas de Cláudia,
minha amada esposa, que tanto me motivou. Também agradeço a Eva e a
Ada, minhas adoráveis filhas, que alegram meu viver, por terem me dado o
apoio necessário. A vocês, obrigado por me compreenderem em momentos
importantes nos quais estive ausente, mesmo estando próximo, em razão dos
esforços por concluir esse trabalho.
Aos meus pais, dedico homenagem e agradecimento. Em especial, à
memória de meu pai, com quem gostaria muito de compartilhar este momento.
Agradeço a minha mãe pela dedicação e orações.
Minha gratidão ao meu orientador, Prof. Robson do Nascimento Fidalgo,
que, antes de tudo, sabe ser gente simples, independente dos títulos que já
possui e dos que venha a possuir. Agradeço pela oportunidade de conviver e
aprender com o excelente profissional, orientando-me, lutando comigo para
conseguirmos nossos objetivos. Não poderia ter tido melhor orientador.
v
“Descobri que não há nada melhor
para o homem do que ser feliz e
praticar o bem enquanto vive.”
(Eclesiastes 3:12)
vi
RESUMO
A MultiDimensional eXpression (MDX) é uma linguagem de consulta
para processamento analítico de dados ou On-line Analytical Processing
(OLAP). Apesar de esta linguagem ser usada pela maioria dos servidores
OLAP, esta não é um padrão de direito. Portanto, tem-se pouca (ou nenhuma)
garantia de que as funções MDX usadas por um servidor OLAP também
possam ser usadas em outros servidores. Neste contexto, de forma a comparar
as funções MDX de um servidor OLAP de código aberto e outro de código
fechado, os servidores Mondrian e Analysis Services, por serem bem aceitos
tanto pela academia quanto pela indústria, foram respectivamente escolhidos.
Para realizar este estudo comparativo, o qual consiste em examinar se existe
diferença entre as gramáticas da linguagem MDX usadas por estes servidores,
será utilizada a seguinte estratégia: identificar quais funções são específicas de
um servidor, quais funções são comuns aos servidores e, dentre as funções
comuns (i.e., com o mesmo nome), se existe diferença de sintaxe entre elas.
De forma a executar este estudo, será apresentado o cenário de testes
aplicados, bem como a ferramenta TestMDX que foi desenvolvida para
automatizar a execução dos testes. Por fim, será apresentada uma análise dos
resultados obtidos.
Palavras-Chave: Estudo Comparativo. Linguagem MDX. OLAP
vii
ABSTRACT
The MultiDimensional eXpression (MDX) is a query language for Online
Analytical Processing (OLAP). Although this language is used by most OLAP
servers, this is not a facto standard. Therefore, there is little (or no) guarantee
that the MDX functions used by an OLAP server can also be used on other
servers. In this context, in order to compare the MDX functions of an OLAP
server open source and other closed source, servers Mondrian and Analysis
Services, to be well accepted by both the academia and by industry, were
respectively chosen. To accomplish this comparative study, which is to examine
whether there are differences between the MDX grammars used by these
servers, we have identified which functions are specific to a server, which
functions are common to the servers and, among the common functions (i.e.,
with the same name), if theirs syntaxes are the same. In order to perform this
study will be presented to the test scenario, as well as the tool TestMDX that
was developed to automate test execution. Finally, we will present an analysis
of the results.
Keywords: Comparative Study. MDX. OLAP
viii
LISTA DE FIGURAS
Figura 2.1 - Esboço e exemplo de modelos estrela [7]. ...................................................................................... 16
Figura 2.2 - Principais conceitos de um Cubo de dados ...................................................................................... 18
Figura 2.3 - Principais operações OLAP .............................................................................................................. 19
Figura 3.1 - Esquema estrela do Data Mart de teste .......................................................................................... 27
Figura 3.2 – Cubo Sales no Analysis Services e Mondrian .................................................................................. 28
Figura 3.3 - Casos de uso da ferramenta TestMDX ............................................................................................ 29
Figura 3.4 - Arquitetura para usar a ferramenta TestMDX ................................................................................ 30
Figura 3.5 - TestMDX: Diagrama de classes de visualização .............................................................................. 31
Figura 3.6 - TestMDX: Diagrama de classes de controle .................................................................................... 32
Figura 3.7 - TestMDX: Tela inicial da ferramenta ............................................................................................... 33
Figura 3.8 - TestMDX: Tela de cadastro de conexões ......................................................................................... 34
Figura 3.9 - TestMDX: Cadastro de caso de teste ............................................................................................... 35
Figura 3.10 - TestMDX: Executar teste automático ............................................................................................ 35
Figura 3.11 - TestMDX: Tela de resumo dos testes ............................................................................................. 36
Figura 3.12 – TestMDX: Layout do repositório de consultas .............................................................................. 36
Figura 3.13 - TestMDX: Arquivo de saida de testes ............................................................................................ 37
Figura 3.14 - TestMDX: Diagrama de atividade de teste automático ............................................................... 37
Figura 4.1 - Esquema do quadro comparativo de funções ................................................................................. 40
Figura A.1 - Arquivos da pasta lib dentro do arquivo mondrian.war ................................................................. 53
Figura A.2 - Arquivo FoodMartCreateData.sql para carga de dados da base FoodMart ................................... 53
Figura A.3 - Pasta de instalação com arquivos copiados ................................................................................... 53
Figura B.1 - Iniciando a instalação do MySQL Connector/NET ........................................................................... 55
Figura B.2 - Data Source com MySQL Data Provider .......................................................................................... 56
Figura B.3 - Parâmetros para conexão com a base foodmart do MySQL ........................................................... 56
Figura B.4 - Modificando valor do parâmetro "Sql Server Mode" ...................................................................... 57
Figura B.5 - Testando a conexão com o MySQL.................................................................................................. 57
Figura B.6 - Definindo credenciais de acesso para o Data Source ...................................................................... 57
Figura B.7 - Finalizando a instalação .................................................................................................................. 58
Figura B.8 - Data Source criado para foodmart.................................................................................................. 58
Figura B.9 - Seleção de tabelas para Data Source View ..................................................................................... 58
Figura B.10 - Data Source View com tabelas de foodmart ................................................................................. 59
Figura B.11 - Regra XMLA_Access (Tela 1) ......................................................................................................... 59
Figura B.12 - Regra XMLA_Access (Tela 2) ......................................................................................................... 59
Figura C.1 - Iniciando instalação do IIS ............................................................................................................... 60
Figura C.2 - Configurações mínimas para o IIS ................................................................................................... 60
Figura C.3 - Iniciando o gerenciador do IIS ......................................................................................................... 61
Figura C.4 - Adicionando pool de aplicativos no IIS ............................................................................................ 61
ix
Figura C.5 - Copiando arquivos do mecanismo XMLA ........................................................................................ 62
Figura C.6 - Colando arquivos copiados na pasta olap do site padrão IIS .......................................................... 62
Figura C.7 - Pasta olap selecionada para conversão de aplicativo ..................................................................... 63
Figura C.8 - Converter para Aplicativo ................................................................................................................ 63
Figura C.9 - Concluindo conversão para aplicativo no IIS ................................................................................... 64
Figura C.10 - Manipulador para dlls do site ....................................................................................................... 64
Figura C.11 - Mapeamento de Script .................................................................................................................. 65
Figura C.12 - Teste de acesso HTTP XMLA .......................................................................................................... 65
Figura D.1 - Arquivos do Mondrian descompactados......................................................................................... 66
Figura D.2 - Pasta do Mondrian criada pelo arquivo mondrian.war no servidor Tomcat .................................. 67
Figura D.3 - Conector jdbc MySQL na pasta lib do Tomcat ................................................................................ 67
Figura D.4 - Navegador acessando o Mondrian OLAP Server ............................................................................ 71
Figura D.5 - Mondrian OLAP Server exibindo dados da base foodmart ............................................................. 71
LISTA DE GRÁFICOS
Gráfico 4.1 - Funções comuns e específicas do Analysis Services e Mondrian .................................................... 41
Gráfico 4.2 - Funções sobrecarregadas do Analysis Services e Mondrian .......................................................... 42
Gráfico 4.3 - Quantidade de sintaxes nos servidores Analysis Services e Mondrian. ......................................... 43
Gráfico 4.4 - Sintaxes iguais e exclusivas no Analysis Services e Mondrian........................................................ 44
x
LISTA DE QUADROS
Quadro 2.1 - Tipos de coleções de membros MDX ............................................................................................. 19
Quadro 2.2 - Sintaxe básica MDX ...................................................................................................................... 21
Quadro 2.3 - Exemplo de consulta básica MDX .................................................................................................. 21
Quadro 2.4- Categorias de Funções MDX ........................................................................................................... 23
Quadro 4.1 – Sintaxes exclusivas do Mondrian .................................................................................................. 44
Quadro 4.2 - Sintaxes exclusivas do Analysis Services ........................................................................................ 45
Quadro D.1 - Arquivo datasource.xml do Mondrian configurado para conectar MySQL ................................... 68
LISTA DE SCRIPTS
Código A.1 - Script para carga de dados na base foodmart do Mysql ............................................................... 54
xi
LISTA DE ABREVIATURAS E SIGLAS
API - Application Programming Interface é um conjunto de rotinas, protocolos e
ferramentas para desenvolvimento de sistemas.
BI - Business Intelligence
DW - Data Warehouse
DM - Data Mart
HTTP - HyperText Transfer Protocol
Java – Uma linguagem de programação orientada a objetos.
JDBC - Java Database Connectivity é uma API do Java para execução de
comandos SQL em banco de dados.
MDX - Multidimensional Expressions é uma linguagem de consulta para
servidores OLAP proposta pela Microsoft em 1997
ODBC - Open Database Connectivity Open é um driver que permite às
aplicações acessarem os dados armazenados em SGBD.
OLAP - On-line Analytical Processing
SGBD - Sistema de Gerenciamento de Banco de Dados
SOAP -Object Access Protocol
SQL - Structured Query Language é a linguagem padrão para manipulação de
dados em banco de dados relacionais.
XML - eXtensible Markup Language é uma linguagem onde os
desenvolvedores podem criar suas próprias marcações. Isso permite que se
estabeleçam padrões, mecanismos de transmissão, interpretação e validação
dos dados contidos no arquivo.
XMLA - XML for Analysis
xii
SUMÁRIO
1. INTRODUÇÃO .................................................................................................................... 14
1.1 APRESENTAÇÃO ......................................................................................................... 14
1.2 MOTIVAÇÃO ................................................................................................................. 14
1.3 OBJETIVOS E CONTRIBUIÇÕES ................................................................................. 15
1.4 ESTRUTURA DO TRABALHO ...................................................................................... 15
2. CONCEITOS BÁSICOS ..................................................................................................... 16
2.1 BANCO DE DADOS PARA OLAP .................................................................................. 16
2.2 LINGUAGEM MDX ......................................................................................................... 19
2.3 CONSIDERAÇÕES FINAIS ........................................................................................... 23
3. ANÁLISE COMPARATIVA DE FUNÇÕES MDX ............................................................... 24
3.1 MATERIAIS .................................................................................................................... 24
3.1.1 TECNOLOGIAS UTILIZADAS ............................................................................. 24
3.2 MÉTODOS ..................................................................................................................... 26
3.2.1 PREPARANDO O DW E O CUBO DE TESTE ................................................... 26
3.2.2 DESENVOLVIMENTO DA FERRAMENTA TestMDX ................................... 28
3.2.3 ESTRATÉGIA PARA SELEÇÃO E ELABORAÇÃO DAS CONSULTAS ...... 38
3.3 CONSIDERAÇÕES FINAIS ........................................................................................... 39
4. RESULTADOS E DISCUSSÕES ....................................................................................... 40
4.1 DIFERENÇAS DE FUNÇÕES MDX DO ANALYSIS SERVICES E MONDRIAN ........... 40
4.2 FUNÇÕES COM SINTAXES EXCLUSIVAS .................................................................. 44
4.3 DIVERGÊNCIAS ENCONTRADAS COM A AJUDA DE TESTMDX .............................. 45
5. CONCLUSÕES ................................................................................................................... 47
5.1 CONSIDERAÇÕES FINAIS ........................................................................................... 47
5.2 TRABALHOS FUTUROS ............................................................................................... 48
REFERÊNCIAS .......................................................................................................................... 49
ANEXO A - SCRIPT PARA CARGA DE DADOS NA BASE FOODMART DO MYSQL .......... 51
APÊNDICE A - CRIANDO A BASE DE DADOS FOODMART NO MYSQL ............................ 52
APÊNDICE B - CONECTANDO O ANALYSIS SERVICES COM O MYSQL ........................... 55
APÊNDICE C - CONFIGURAÇÃO DO IIS PARA ACESSO HTTP XMLA ............................... 60
APÊNDICE D - INSTALAÇÃO E CONFIGURAÇÃO DO MONDRIAN ..................................... 66
APÊNDICE E - COMPARAÇÃO DE FUNÇÕES MDX .............................................................. 72
xiii
APÊNDICE F - COMPARAÇÃO DA SINTAXE MDX ................................................................ 78
APÊNDICE G - CONSULTAS TESTADAS COM A FERRAMENTA TESTMDX ..................... 87
APÊNDICE H – FUNÇÕES SOBRECARREGADAS .............................................................. 105
14
1. INTRODUÇÃO
Neste Capítulo são apresentadas as motivações e os objetivos que
levaram ao desenvolvimento desta dissertação. Além disso, também é descrita
a estrutura na qual os demais Capítulos deste trabalho estão organizados.
1.1 APRESENTAÇÃO OLAP (OnLine Analytical Processing) [1] é uma tecnologia para realizar
consultas analíticas que permitem cruzar dados (e.g. vendas por ano, tipo de
produto e escolaridade do cliente) e visualizá-los com diferentes níveis de
detalhes (e.g. vendas por ano, semestre, mês e dia). OLAP por muito tempo
não teve uma linguagem de consulta padrão. A primeira proposta [2] foi feita
em 1997, quando a Microsoft disponibilizou a linguagem MDX
(MultiDimensional eXpressions) [2] como a linguagem de consulta para a API
(Application Programming Interface) ODBO (OLE DB for OLAP) [3].
Posteriormente, no ano de 2001, com o intuito de prover uma API
independente de linguagem de Programação, a Microsoft e a Hyperion
especificaram o padrão XML4A (XML for Analysis) [3], o qual é baseado em
Serviços Web [4] e usa MDX como linguagem de consulta.
Embora MDX não seja um padrão “de direito”, dada a sua ampla
aceitação por várias ferramentas OLAP (e.g., MicroStrategy, Oracle
Corporation, SAS, SAP, Teradata, JasperSoft, Cognos, Business Objects,
Crystal Reports, Microsoft Excel e Microsoft Reporting Services), esta é
considerada um “padrão de fato”. Neste contexto, dada à importância de MDX
e a falta de um padrão oficial da mesma, este trabalho irá comparar as funções
MDX dos servidores Analysis Service e Mondrian. A seguir, é apresentada a
motivação para realizar este trabalho.
1.2 MOTIVAÇÃO As principais motivações para o desenvolvimento deste trabalho são: 1)
a linguagem MDX é utilizada pela maioria dos servidores OLAP, porém esta
não é um padrão de direito; 2) o Analysis Service e o Mondrian são servidores
OLAP baseados em MDX [13] bem conceituados; 3) não há garantia de que
todas as funções MDX do Analysis Service possam ser executadas no
Mondrian e vice-versa; 4) não se tem conhecimento de um trabalho que tenha
15
feito uma análise comparativa de funções MDX desses servidores OLAP; Por
fim, 5) as descobertas obtidas a partir deste trabalho serão úteis para orientar a
escrita de consultas MDX que precisam ser executadas nos dois servidores
OLAP em questão (e.g. em projetos de migração/integração de sistemas OLAP
e/ou desenvolvimento de soluções OLAP que devem rodar tanto no Mondrian
quanto no Analysis Services).
1.3 OBJETIVOS E CONTRIBUIÇÕES O objetivo geral deste trabalho é realizar uma análise comparativa de
funções MDX nos servidores OLAP Analysis Services e Mondrian. A partir do
objetivo geral, podem-se descrever os seguintes objetivos específicos, os quais
correspondem às contribuições deste trabalho: 1) especificação de uma
estratégia para selecionar as funções MDX que devem ser testadas nos
servidores OLAP analisados; 2) Identificação das funções que são exclusivas
do Mondrian; 2) Identificação das funções que são exclusivas do Analysis
Services; 3) Identificação das funções comuns ao Mondrian e ao Analysis
Services; 4) Identificação das divergências na sintaxe das funções comuns aos
servidores; e 5) especificação e desenvolvimento de uma ferramenta para
simultaneamente testar consultas MDX nos dois servidores OLAP em questão.
1.4 ESTRUTURA DO TRABALHO Visando atingir os objetivos desta dissertação, bem como apresentar alguns
conceitos e tecnologias relacionadas, os demais Capítulos estão organizados da
seguinte maneira: no Capítulo 2, é apresentada a fundamentação teórica para o
entendimento deste trabalho, abordando os principais conceitos relacionados com
base de dados para suporte à decisão (Data Warehouse), Processamento Analítico
(ou simplesmente OLAP) e a linguagem MDX; no Capítulo 3, são apresentados os
materiais e os métodos aplicados na construção deste trabalho; no Capítulo 4, é
feita uma discussão sobre os resultados obtidos; e, por fim, no Capítulo 5, são
apresentadas as conclusões, as limitações do estudo e propostas para trabalhos
futuros.
16
2. CONCEITOS BÁSICOS
Neste Capítulo são apresentados os principais conceitos relacionados à
OLAP, os quais são fundamentais para possibilitar um melhor entendimento
dos próximos capítulos desta dissertação.
2.1 BANCO DE DADOS PARA OLAP Um DW (Data Warehouse) [1], [5], [6] é um banco de dados para dar
suporte à tomada de decisão que armazena uma visão histórica e sem
heterogeneidade das principais fontes de dados de uma corporação. Devido ao
elevado custo e complexidade de construir um DW, uma opção mais barata e
simples é construir um DM (Data Mart) [1], [5], [6]. Diferentemente dos DW, que
correspondem a uma visão global dos dados, os DM são específicos para um
assunto da corporação (e.g., um setor ou departamento). A maioria dos
DM/DW é construído usando um SGBD (Sistema de Gerenciamento de Banco
de Dados) relacional e seu esquema de dados é normalmente modelado a
partir de um esquema Estrela [1], [5], [6], o qual possui tabelas de dois tipos: 1)
Dimensão - tabela desnormalizada projetada para armazenar as descrições
textuais do negócio a ser analisado e 2) Fato - tabela normalizada projetada
para armazenar o conjunto de chaves estrangeiras para as chaves primárias
das dimensões e as medidas numéricas do negócio a ser analisado. A Figura
2.1 ilustra um esboço (A) e um exemplo (B) de um esquema estrela.
Figura 2.1 - Esboço e exemplo de modelos estrela [7].
17
Várias ferramentas podem ser usadas para consultar os dados de um
DW/DM. Uma dessas ferramentas é a OLAP (Online Analytical Processing) [1]
[8]. OLAP é uma tecnologia utilizada para realizar consultas de suporte à
decisão sobre bases de dados conhecidas como cubos de dados [1] [8], os
quais correspondem a uma visão (materializada ou não) de um DW. Os
principais conceitos sobre cubo de dados são ilustrados na Figura 2.2 e
apresentados a seguir [9] [10]:
Dimensões – Correspondem aos eixos de análise do cubo de
dados. Por exemplo: DM_Cliente, DM_Localizacao e DM_Tempo;
Níveis – Equivalem aos atributos de uma dimensão. Por exemplo:
Unidade Federativa, Estado Civil e Mês;
Hierarquias – Representam diferentes visões ordenadas dos
níveis de uma dimensão. Ressalta-se que uma dimensão pode ter
mais de uma hierarquia. Por exemplo, uma dimensão DM_Tempo
pode ter uma hierarquia ano > semestre > mês e outra ano > mês
> dia;
Medidas – correspondem a atributos mensuráveis. Por exemplo,
unidades vendidas, vendas em reais e lucro;
Membros – são os dados de um nível. Por exemplo, janeiro,
fevereiro, março e abril são membros de um nível mês;
Fatos ou células – correspondem aos valores de uma medida que
é obtido a partir da interseção de membros de diferentes
dimensões. Por exemplo, mouse Microsoft em 2013, vendeu 200
unidades.
18
Figura 2.2 - Principais conceitos de um Cubo de dados
A partir de um cubo de dados, várias operações OLAP podem ser
executadas [11]. A Figura 2.3 ilustra estas operações, as quais são
introduzidas a seguir:
Roll-up: agregação dos dados para um nível menos detalhado.
Por exemplo, ir de um nível mês para um nível semestre;
Drill-down: agregação dos dados para um nível mais detalhado.
Esta operação é inversa ao Roll-up;
Slice: projeção sobre um ou mais níveis de uma dimensão do
cubo de dados. Por exemplo, vendas de produtos por marca, ano
e tipo de fornecedor;
Dice: seleção sobre um ou mais membros de um nível do cubo de
dados. Por exemplo, vendas em PE, no ano de 2011 e de cliente
solteiros;
Pivoting/Rotate - rotação dos eixos do cubo de dados. Por
exemplo, venda de produtos por ano e tipo de cliente ou venda de
produtos por tipo de cliente e ano.
19
Figura 2.3 - Principais operações OLAP
2.2 LINGUAGEM MDX MultiDimensional eXpression (MDX) [12] é uma linguagem de consulta a
cubo de dados que tem uma sintaxe declarativa semelhante à linguagem SQL.
Entretanto, apesar das semelhanças, MDX não é uma extensão de SQL, pois
esta linguagem tem propósitos, funções e operadores distintos. A seguir, são
apresentados os principais conceitos para manipular dados em MDX.
Um dado em MDX é conhecido como membro. Por exemplo, Masculino
Recife e Janeiro. Os membros podem ser especificados pelo seu nome único
(e.g., [Tempo].[Ano].[Mes].[Abril de 2013]), pelo nome qualificado (e.g.,
[Tempo]. [Ano].[2013].[Trimestre 2].[Abril de 2013]), pelo nome abreviado (e.g.,
[Tempo]. [Abril de 2013]), ou retornado por uma função MDX (e.g.,
PrevMember, Parent , FirstChild).
Existem dois tipos de coleções de membros: tuplas e conjuntos. No
primeiro caso, todos os membros da coleção devem ser de dimensões
diferentes. Por sua vez, no segundo caso, a coleção é formada por um
conjunto de membros de uma mesma dimensão. Ressalta-se que uma tupla é
delimitada por parênteses “( )” e um conjunto por chaves “{ }”. No Quadro 2.1
são apresentados exemplos destes tipos de coleções.
Quadro 2.1 - Tipos de coleções de membros MDX
20
Tipo de
coleção Exemplo
Conjunto {[Tempo].[2010].[Trimestre1],[Tempo].[2011].[Trimestre1],[Tempo].[2012].[Trimestre1]}
Tupla ([Tempo].[2013], [Loja].[Brasil], [Produto].[Bebida])
Conjunto
de Tuplas
{([Tempo].[2013], [Loja].[Brasil].[AL], [Produto].[Bebida]), ([Tempo].[2013], [Loja].[Brasil].[PB],
[Produto].[Bebida]), ([Tempo].[2013], [Loja].[Brasil].[PE], [Produto].[Bebida])}
Além de permitir manipular dados (membros), a MDX também permite
manusear metatados (i.e., dimensões, hierarquias e níveis). Por exemplo, para
referenciar a dimensão Tempo, pode-se fazer pelo nome da dimensão (e.g.,
[Tempo]), por um membro (e.g., [Tempo].[2013].Dimension), por uma
hierarquia (e.g., [Tempo].[Periodo Fiscal].Dimension), ou por um nível (e.g.,
[Tempo].[Periodo Fiscal].[Ano].Dimension). Para referenciar a hierarquia
Periodo Fiscal da dimensão Tempo pode-se fazer pelo nome da hierarquia
(e.g., [Tempo].[Periodo Fiscal]), por um nível (e.g., [Tempo].[Periodo
Fiscal].[Ano].Hierarchy), ou por um membro da hierarquia (e.g., [Time].[Periodo
Fiscal].[2012].Hierarchy). Por fim, para referenciar um nível Mês da dimensão
Tempo usando a hierarquia padrão, pode-se fazer [Tempo].[Mes],
[Tempo].Levels(2) ou [Tempo].[Mes].[Abril].Level. Caso seja necessário
referenciar o nível Mês da hierarquia Periodo Fiscal da dimensão Tempo, pode-
se fazer [Tempo].[Periodo Fiscal].[Mes], [Tempo].[Periodo Fiscal].Levels(2).
[Tempo].[Periodo Fiscal].[Mes].[Abril].Level. Ressalte-se que o uso de
colchetes só é obrigatório quando o nome do identificador (dado ou metadado)
contiver números, espaços em branco, palavras reservadas da linguagem MDX
ou caracteres especiais.
A partir do entendimento dos principais identificadores de MDX, pode-se
escrever uma consulta de acordo com a sintaxe apresentada no Quadro 2.2
[12].
21
Quadro 2.2 - Sintaxe básica MDX
SELECT [<especificação_do_eixo>
[, <especificação_do_eixo>...]]
FROM <nome_do_cubo>
[WHERE <especificação_de_Seleção>]
No Quadro 2.2 pode-se observar que apenas as cláusulas SELECT e
FROM são obrigatórias. Além disso, onde aparece <especificação_do_eixo>,
<nome_do_cubo> e <especificação_de_Seleção>, pode-se definir os eixos que
serão usados na consulta, o nome do cubo a ser consultado e o eixo que irá
restringir a consulta, respectivamente. Basicamente, uma consulta MDX tem
três eixos: coluna (columns ou 0), linha (rows ou 1) e restritivo. Os dois
primeiros são usados para projetar dados (operação de Slice) e o último para
selecionar dados (operação de Dice). O Quadro 2.3 mostra um exemplo básico
de uma consulta MDX, o qual tem no eixo coluna o membro
[Medidas].[Unidades vendidas], no eixo linha o conjunto {[Tempo].[2011],
[Tempo].[2012]} e no eixo restritivo a tupla ([Loja].[Brasil].[PE],
[Produto].[Bebida]). Nota-se que os eixos de uma consulta MDX são formados
a partir de membros, conjuntos e tuplas. Uma boa documentação de MDX pode
ser consultada em http://msdn.microsoft.com/pt-br/library/ms145506.aspx ou
http://mondrian.pentaho.com/documentation/mdx.php.
Quadro 2.3 - Exemplo de consulta básica MDX
SELECT
[Medidas].[Unidades vendidas] ON COLUMNS,
{[Tempo].[2011], [Tempo].[2012]} ON ROWS
FROM [Vendas]
WHERE ([Loja].[Brasil].[PE], [Produto].[Bebida])
A linguagem MDX tem várias categorias de funções, estas são
apresetadas a seguir:
22
Funções de matriz - fornecem matrizes para serem usadas em
UDFs (i.e., funções definidas pelo usuário);
Funções de dimensão - retornam uma referência a uma dimensão
a partir de uma hierarquia, nível ou membro;
Funções de hierarquia - retornam uma referência a uma
hierarquia a partir de um nível ou membro;
Funções de nível - retornam uma referência a um nível a partir de
um membro, dimensão, hierarquia ou expressão de cadeia de
caracteres;
Funções lógicas - executam operações lógicas e comparações
em objetos e expressões;
Funções de membro - retornam uma referência a um membro a
partir de outros objetos ou de uma expressão de cadeia de
caracteres;
Funções matemáticas - executam operações matemáticas e
estatísticas em objetos e expressões;
Funções de conjunto - retornam uma referência a um conjunto a
partir de outros objetos ou de uma expressão de cadeia de
caracteres;
Funções de cadeia de caracteres - retornam valores da cadeia de
caracteres a partir de outros objetos ou do servidor;
Funções de tupla - retornam uma referência a uma tupla a partir
de um conjunto ou de uma expressão de cadeia de caracteres.
No Quadro 2.4 são apresentados exemplos de cada uma das categorias
de funções MDX. Na próxima seção são apresentadas as considerações finais
deste capítulo.
23
Quadro 2.4- Categorias de Funções MDX
Categoria de função Exemplo
Funções de matriz SELECT MinhaUDF([Tempo].[Ano].Members) on 0 FROM [Vendas]
Funções de dimensão SELECT [Tempo].[Ano].[1997].Dimension on 0 FROM [Vendas]
Funções de hierarquia
WITH MEMBER MEASURES.nomehierarquia AS
[Tempo].[Ano].[1997].Hierarchy.Name
SELECT MEASURES.nomehierarquia ON 0,
[Tempo].[Ano].Members ON 0 FROM [Vendas]
Funções de nível
WITH MEMBER MEASURES.nomenivel AS [Tempo].[Ano].Level.Name
SELECT MEASURES.nomenivel ON 0,
[Tempo].[Ano].Members ON 0 FROM [Vendas]
Funções lógicas
WITH MEMBER MEASURES.[IsLeafDemo] AS
IsLeaf([Tempo].[Ano].[1997])
SELECT MEASURES.[IsLeafDemo] ON 0 FROM [Vendas]
Funções de membro
WITH MEMBER MEASURES.[CurrentMemberDemo] AS
[Tempo].[Ano].CurrentMember.Name
SELECT MEASURES.[CurrentMemberDemo] ON 0,
[Tempo].[Ano].Members ON 1 FROM [Vendas]
Funções matemáticas
WITH MEMBER [Measures].[soma] AS
SUM({[Tempo].[Ano].[1997],[Tempo].[Ano].[1997]})
SELECT [Measures].[soma] on 0 FROM [Vendas]
Funções de conjunto
SELECT [Measures].[Unidades] ON 0,
Crossjoin([Tempo].[Ano].Members,
[Produto].[Categoria].Members) ON 1 FROM [Vendas]
Funções de cadeia de
caracteres
SELECT Generate([Tempo].[Ano].Members
, {[Measures].[Unidades]}) ON 0 FROM [Vendas]
Funções de tupla
WITH SET demotupla AS '[Tempo].[Ano].Members *
[Produto].[Categoria].Members'
MEMBER MEASURES.demoitemtupla AS
TupleToStr(demotupla.Item(1))
SELECT MEASURES.demoitemtupla ON 0 FROM [Sales]
2.3 CONSIDERAÇÕES FINAIS OLAP é uma tecnologia utilizada para dar suporte à tomada de decisão. Os
servidores OLAP que se destacam são o Analysis Services e o Mondrian. Ambos
utilizam a linguagem MDX para consultas. Esta linguagem permite manipular dados
(membros) que, por sua vez, são organizados em níveis, hierarquias e dimensões
de um cubo. Além disso, MDX utiliza coleções de membros, e estes elementos
também são utilizados como argumentos em funções MDX. No próximo Capítulo,
são apresentados os materiais e métodos empregados no desenvolvimento deste
trabalho.
24
3. ANÁLISE COMPARATIVA DE FUNÇÕES MDX
Neste Capítulo descrevem-se os materiais (tecnologias utilizadas) e
métodos (procedimentos realizados) que foram empregados durante o
desenvolvimento deste trabalho.
3.1 MATERIAIS Nesta seção são apresentadas as tecnologias utilizadas na preparação
do ambiente de teste e no desenvolvimento da ferramenta de testes.
3.1.1 TECNOLOGIAS UTILIZADAS
Para a realização deste trabalho, foram utilizadas as seguintes
tecnologias:
Servidores OLAP: Mondrian e Analysis Services;
SGBD para armazenar e gerenciar o DW: MySQL Server;
Ferramenta para construção de cubos no Analysis Services:
Microsoft Visual Studio 2008;
Linguagem de programação: Java;
Ambiente de desenvolvimento: Eclipse;
APIs para acessar os servidores OLAP: XMLA e OLAP4J;
Driver XMLA para conexão aos servidores OLAP: XmlaOlap4jDriver
Driver JDBC para conexão ao DW: MySQL Connector/JDBC 5.1.10 e
MySQL Connector/Net 6.6.5;
Driver JDBC para acessar a base de dados da ferramenta de testes
no SGBD SQLite: SQLite-jdbc-3.7.2.
Servidores Web: Apache Tomcat e Microsoft Internet Information
Services;
Os servidores OLAP selecionados para realizar os testes foram o
Mondrian e o Analysis Services, pois ambos usam a linguagem MDX e são os
representantes mais populares de servidores OLAP, baseados em tecnologias
de código aberto e fechado, respectivamente. O Mondrian é da Pentaho e pode
25
ser obtido no site http://sourceforge.net/projects/mondrian/. Por sua vez, o
Analysis Services é da Microsoft e é distribuído com o SQL Server.
Dado que o Mondrian possui um conjunto de cubos para testes, o cubo
Sales (ver seção 3.2.1) foi escolhido para testar as funções MDX deste
servidor. A escolha deste cubo foi motivada pelo fato dele ilustrar um exemplo
de vendas de um supermercado, o qual é bem conhecido e de fácil
entendimento. Para garantir a uniformidade de fonte de dados, o cubo Sales foi
replicado no Analysis Services. Para isto, utilizou-se o Visual Studio 2008 - a
ferramenta da Microsoft para criação de cubos no Analysis Services. Por fim,
sobre o DW de teste, como os cubos de teste do Mondrian são criados a partir
do DW Foodmart com o SGBD MySQL Server (ver seção 3.2.1), estes (DW e
SGBD) foram mantidos.
Os testes de funções MDX nos servidores Mondrian e Analysis
Services foram realizados a partir do desenvolvimento da ferramenta
TesteMDX (ver seção 3.2.2). Esta ferramenta foi construída em Java utilizando
o ambiente de desenvolvimento integrado Eclipse, pois este é fácil de usar e
tem uma grande comunidade de usuários. Além disso, também foi necessário
utilizar: 1) as API XMLA e OLAP4J para submeter às consultas MDX e
recuperar seus resultados; 2) o driver genérico XmlaOlap4jDriver para conectar
ao Analysis Service e Mondrian; 3) os drivers MySQL Connector/JDBC 5.1.10 e
MySQL Connector/Net 6.6.5 para, respectivamente, configurar o acesso do
Mondrian e do Analysis Services ao DW no MySQL; 4) o driver SQLite-jdbc-
3.7.2 para permitir o armazenamento dos resultados dos testes realizados pela
ferramenta TestMDX em um banco de dados SQLite; Por fim, 5) o Apache
Tomcat e Microsoft Internet Information Services como servidores Web para o
Mondrian e o Analysis Services, respectivamente.
Sobre o equipamento utilizado para realizar os testes, este foi um
notebook com processado Pentium® Dual-Core 2.30GHz, 3 GB de Memória
RAM, HD de 320 GB e sistema operacional Windows 7 Professional (32 Bits).
26
3.2 MÉTODOS Nesta seção são apresentados os procedimentos realizados para o
desenvolvimento deste trabalho. Primeiramente, é apresentado como o DW e o
Cubo de teste foram construídos. Depois, apresenta-se o desenvolvimento da
ferramenta TestMDX. Na sequência, apresenta-se a estratégia para seleção e
elaboração das consultas.
3.2.1 PREPARANDO O DW E O CUBO DE TESTE
Para assegurar a homogeneidade dos dados, utilizou-se um único DW,
o FoodMart. Este DW foi escolhido, pois é livremente distribuído com a atual
versão do Mondrian e foi distribuído com as antigas versões do Analysis
Services (i.e., até o SQL Server 2000). O SGBD escolhido para gerenciar o DW
foi o MySQL Server, pois este é de distribuição gratuita e o script SQL de
criação do DW Foodmart é baseado no dialeto deste SGBD. Para instanciar o
DW FoodMart foi utilizado o script SQL apresentado no ANEXO A e realizado o
procedimento descrito no APÊNDICE A. O DW FoodMart tem 22 (vinte e duas)
tabelas de dimensões e 2 (duas) tabelas de fatos. Para os testes realizados
neste trabalho, foram utilizadas apenas 6 (seis) tabelas de dimensões (i.e.,
Customer, Store, Promotion, Product, Product_class e Time) e a tabela de fatos
Sales_Fact_1997. A Figura 3.1 mostra o esquema estrela do Data Mart de
teste.
Com base no Data Mart de teste, o Mondrian disponibiliza o cubo
Sales. Dado que este cubo não existe na versão 2008 do Analysis Services, foi
necessário reconstruí-lo/replicá-lo no Analysis Services. Ressalta-se que, para
construir este cubo no Analysis Services, foi utilizado o MySQL Connector/Net
para conectar o Visual Studio à base de dados foodmart do MySQL (ver
APÊNDICE B). No Mondrian, esta conexão é feita usando o MySQL
Connector/JDBC. Dessa forma, tanto o Mondrian quanto o Analysis Services
utilizaram o mesmo esquema para o cubo Sales. Na Figura 3.2 mostra-se o
esquema do cubo Sales no Analysis Sevice (em tons coloridos) e no Mondrian
(em tons de cinza). Nesta figura o cubo Sales tem 4 medidas convencionais
(e.g., Store Cost e Unit Sales), 3 medidas calculadas (e.g., Profit e Profit last
27
Period) tem 11 dimensões (e.g., Customers e Time), cada uma dessas
dimensões tem suas hierarquias (e.g., a dimensão Time tem as hierarquias
Time e Weekly), cada uma das hierarquias tem seus nívies (e.g., a hierarquia
Time tem os níveis Year, Quarter e Month).
Figura 3.1 - Esquema estrela do Data Mart de teste
28
Figura 3.2 – Cubo Sales no Analysis Services e Mondrian
3.2.2 DESENVOLVIMENTO DA FERRAMENTA TestMDX
Embora o Analysis Services e o Mondrian disponham de ferramentas
para executar consultas MDX, estas ferramentas não permitem, ao mesmo
tempo, executar as consultas no Analysis Services e no Mondrian. Além disso,
não permitem executar um script com várias consultas, tampouco obter e
registrar, em um arquivo, informações sobre quais consultas foram executadas
com sucesso (ou não) nos dois servidores. Dadas estas limitações, foi
necessário desenvolver a ferramenta TestMDX para executar os testes de
funções MDX nestes servidores. O desenvolvimento desta ferramenta justifica-
se pela necessidade de verificar se de fato as sintaxes das funções testadas
são executadas conforme a especificação. A ferramenta TestMDX é capaz de
executar simultaneamente as consultas nos dois servidores OLAP e registrar o
resultado dos testes para posterior análise. Na Figura 3.3 mostra-se os casos
29
de uso da ferramenta TestMDX. Nesta Figura tem-se o caso de teste
“Cadastrar Conexões”, o qual permite ao usuário cadastrar conexões com
servidores OLAP; o caso de uso “Cadastrar Casos de Testes” que permite ao
usuário cadastrar os casos de testes a serem executados e por fim, o caso de
uso “Executar Testes”, o qual, com base nas conexões e casos de testes
previamente cadastrados, permite que os usuários executem vários testes
simultaneamente nos dois servidores OLAP.
Figura 3.3 - Casos de uso da ferramenta TestMDX
Na Figura 3.4 apresenta-se a arquitetura de software para uso da
ferramenta TestMDX. Nesta Figura observam-se três camadas: Dados (o DW),
Serviço OLAP (ilustrada pelos servidores Mondrian e Analysis Service) e
Cliente (a ferramenta TestMDX). Além disso, também é possível observar o
uso das API OLAP4J e JDBC. Para acessar os servidores OLAP via OLAP4J
utilizou-se o driver genérico XmlaOlap4jDriver, pois ainda não existe um driver
OLAP4J nativo para o Analysis Service. Ressalta-se que os servidores OLAP
poderiam ser acessados usando apenas a API XMLA. Contudo, dado que
manipular elementos XML é mais complexo do que manipular objetos Java,
optou-se pela API OLAP4J. Para acessar a base de dados, que armazena os
resultados dos testes realizados com a ferramenta TestMDX, utilizou-se a API
30
SQLite-JDBC. Também foram utilizadas as APIs MySQL Connector/Net e
MySQL Connector/JDBC para conectar, respectivamente, o Analysis Services
e o Mondrian ao DW de testes.
Figura 3.4 - Arquitetura para usar a ferramenta TestMDX
Na implementação da ferramenta, as classes foram divididas em duas
categorias. A primeira delas é composta por classes de interface gráfica do
usuário. A segunda é composta por classes de controle da ferramenta. São
estas classes que executam as atividades de processamento e controle dos
testes. O diagrama de classes apresentado na Figura 3.5 mostra as classes
gráficas da ferramenta TestMDX. Estas classes utilizam a interface IFachada
para se comunicar com a camada que contém as classes de controle (ver
Figura 3.6).
31
Figura 3.5 - TestMDX: Diagrama de classes de visualização
Na Figura 3.5, a classe “TPrincipal” cria e controla a primeira tela da
ferramenta TestMDX (ver Figura 3.7); esta contém os menus que dão acesso
às demais telas da ferramenta. Já a classe “TCadastrarConexoes” possui
métodos para manter dados que permitem à ferramenta conectar-se aos
servidores OLAP. A classe “TCadastrarCasosTestes” mantém dados dos casos
de testes, ou seja, as conexões que serão utilizadas para o teste, além dos
nomes dos arquivos de entrada e de saída do teste. Por fim, a classe
“TTesteAutomatico” pemite a seleção e execução automática de um caso de
32
teste. Estas classes, com exceção de “TPrincipal”, utilizam os métodos
existentes na interface “IFachada” para realizar parte de suas operações.
Figura 3.6 - TestMDX: Diagrama de classes de controle
Na Figura 3.6, a classe “TestarConexaoOLAPMDX” usa dados
previamente cadastrados para conectar com os servidores e fazer teste de
conexão, além de verificar a existência de cubos e metadados. Já a classe
“ProcessarTesteAutomatico” é responsável por controlar o processamento de
consultas automáticas. Esta classe faz a leitura do arquivo de consultas MDX e
controla o fluxo de execução destas nos servidores OLAP. A classe
“ExecutarConsulta” é instanciada para cada um dos servidores. Dessa forma,
cada instância da classe “ExecutarConsulta” representa uma consulta
executada em um servidor. A classe “TestarMDXOlapServidor” faz a conexão
com os servidores OLAP; através do protocolo XMLA, envia a consulta e lê
seu resultado . Por fim, a classe “TExibirResultado” mostra na tela a síntese do
processamento do teste automático.
33
A ferramenta TestMDX foi desenvolvida utilizando a linguagem de
programação Java. Os pré-requisitos para o funcionamento adequado da
ferramenta TestMDX são: (1) os servidores OLAP devidamente configurados
para prover acesso XMLA; e (2) os servidores com a mesma base de dados
configurada e o mesmo esquema de cubo OLAP para fins de testes. A tela
inicial da ferramenta TestMDX é mostrada na Figura 3.7.
Figura 3.7 - TestMDX: Tela inicial da ferramenta
Nesta tela (Figura 3.7) existem três botões, o primeiro dá acesso ao
cadastro de conexões com os servidores OLAP, o segundo ao cadastro de
casos de testes e o terceiro dá acesso à execução de testes nos servidores.
Através dos menus também é possível acessar estas opções da ferramenta.
34
Figura 3.8 - TestMDX: Tela de cadastro de conexões
Antes de realizar um teste automático com a ferramenta TestMDX, é
preciso cadastrar conexões com os servidores OLAP. Na tela de cadastro de
conexões (ver Figura 3.8), o usuário seleciona o tipo de conexão (e.g.,
Mondrian ou Analysis Services) e informa os dados necessários para que a
ferramenta possa estabelecer uma conexão com os servidores OLAP. Depois
disso, são cadastrados os casos de testes (ver Figura 3.9), informando as
conexões que serão utilizadas, bem como o arquivo que contém as consultas a
serem testadas e o arquivo que terá a saída dos testes. A estrutura desses
arquivos é ilustrada nas Figuras 3.12 e 3.13, respectivamente. Feito isso, o
usuário acessa a tela de execução de teste automático (ver Figura 3.10),
seleciona um caso de teste e inicia a execução do teste automático. Por fim, a
tela de saída do teste é exibida para o usuário (ver Figura 3.11).
35
Figura 3.9 - TestMDX: Cadastro de caso de teste
Na ferramenta TestMDX, um caso de testes (ver Figura 3.9)
corresponde a um registro contendo: a) os dados das conexões que serão
utilizadas para execução de consultas MDX; b) o nome do arquivo que contém
todas as consultas MDX (i.e., repositório de consultas) que serão testadas nos
servidores OLAP; e c) o nome do arquivo de saída no qual são registrados os
resultados dos testes.
Figura 3.10 - TestMDX: Executar teste automático
36
Figura 3.11 - TestMDX: Tela de resumo dos testes
Figura 3.12 – TestMDX: Layout do repositório de consultas
Um artefato de software importante para a execução de testes
automáticos é o arquivo Excel, que funciona como repositório de consultas
MDX. Este arquivo (ver Figura 3.12) é formado pelas colunas “A”, “B” e “C”,
sendo obrigatório apenas o preenchimento das duas primeiras. A primeira linha
(o cabeçalho) não é considerada no processamento dos testes e descreve o
37
significado de cada coluna. Outro artefato importante é o arquivo resultante da
execução dos testes. Neste arquivo (ver Figura 3.13) são gravadas as
mensagens retonadas pelos servidores durante o teste, além, do status do
teste em cada um dos servidores.
Figura 3.13 - TestMDX: Arquivo de saida de testes
Figura 3.14 - TestMDX: Diagrama de atividade de teste automático
38
O diagrama de atividade apresentado na Figura 3.14 ilustra como os
testes são realizados pela ferramenta TestMDX. Nesta Figura, tem-se a leitura
do arquivo com as consultas MDX. Depois, enquanto não for final do arquivo,
cada consulta será lida e executada nos servidores Analysis Services e
Mondrian. Ao chegar no final do arquivo de testes, é exibida uma tela com
resultados do teste, encerrando os testes.
3.2.3 ESTRATÉGIA PARA SELEÇÃO E ELABORAÇÃO DAS CONSULTAS
Após consultar as referências oficiais de MDX do Mondrian
(http://mondrian.pentaho.com/documentation/mdx.php) e do Analysys Service
(http://msdn.microsoft.com/en-us/library/ms145970.aspx), constatou-se que a
quantidade de funções MDX do Mondrian (217) é diferente da quantidade de
funções MDX do Analysis Services (145) - ver APÊNDICE E. Dada esta
diferença, como não faz sentido testar todas as funções destes servidores, foi
necessário definir uma estratégia para selecionar quais funções seriam
comparadas, analisadas e executadas. Ou seja :
1- Selecionar as funções com o mesmo nome em ambos os
servidores OLAP;
2- Verificar a sintaxe básica dessas funções (apenas foram
considerados os parâmetros obrigatórios) a fim de excluir as
funções com mesmo nome, mas sintaxes divergentes;
3- Identificar as funções sobrecarregadas (considerando apenas os
parâmetros obrigatórios) a fim de elaborar uma consulta para
cada forma de sintaxe destas funções;
4- Elaborar uma consulta para cada função com o mesmo nome e
sintaxe;
5- Executar teste nos servidores OLAP, usando a ferramenta
TestMDX, para verificar se as sintaxes das funções comuns, de
fato, funcionam conforme especificado na documentação do
Analysis Services e Mondrian.
39
3.3 CONSIDERAÇÕES FINAIS Este capítulo apresentou as tecnologias utilizadas para compor o
ambiente de teste. Também apresentou a preparação do DW e do cubo de
testes. Além disso, foi apresentada a ferramenta TestMDX, desenvolvida para
automatizar testes de consultas MDX nos servidores Analysis Services e
Mondrian. Também foi apresentada uma estratégia para seleção e elaboração
das consultas que foram testadas. Por fim, foram identificadas para cada um
dos servidores as funções exclusivas, as sobrecarregadas e as com sintaxes
divergentes.
40
4. RESULTADOS E DISCUSSÕES
Este Capítulo apresenta as diferenças identificadas nas funções MDX
dos servidores Analysis Services e Mondrian. Também apresenta uma análise
da quantidade de funções comuns, específicas, sobrecarregadas e de sintaxes
do Analysis Services e Mondrian. Além disso, apresenta as funções com
sintaxes exclusivas nestes servidores. Por fim, apresenta divergências
encontradas com a ajuda da ferramenta TestMDX.
4.1 DIFERENÇAS DE FUNÇÕES MDX DO ANALYSIS SERVICES E MONDRIAN
A partir das 217 (duzentos e dezessete) funções MDX do Mondrian e
145 (cento e quarenta e cinco) funções MDX do Analysis Services foram
identificadas as funções com o mesmo nome nos dois servidores (i.e., 104
funções). No APÊNDICE E tem-se um quadro destacando em amarelo as
funções com o mesmo nome. Neste quadro, cada função destacada na coluna
do Analysis Services tem um número que corresponde a sua posição na coluna
do Mondrian e um contador das funções com o mesmo nome. A Figura 4.1
ilustra um trecho deste quadro. Observa-se nesta ilustração que a função
AllMembers é comum aos dois servidores (está destacada em amarelo),
aparece na terceira posição da coluna “Analysis Service” (sexta posição da
coluna “Mondrian”) e corresponde a terceira função comum aos servidores
OLAP.
Figura 4.1 - Esquema do quadro comparativo de funções
Comparando a quantidade de funções do Analysis Services com as do
Mondrian, constatou-se que o Mondrian tem 72 (setenta e duas) funções a
mais que o Analysis Services (i.e., 217-145). Além disso, constatou-se (ver
Gráfico 4.1) que há mais funções específicas no Mondrian (217 – 104 = 113 ou
41
52,07%) do que no Analysis Services (145 – 104 = 41 ou 28,28%). Ademais,
enquanto a maioria das funções do Analysis Services (104 ou 71,72% - ver o
lado esquerdo do Gráfico 4.1) pode ser executada no Mondrian, a maioria das
funções do Mondrian (113 ou 52,07% - ver o lado direito do Gráfico 4.1) não
pode ser usada no Analysis Services. Ou seja, consultas MDX que executam
no Analysis Services têm mais chances de serem executadas no Mondrian.
Gráfico 4.1 - Funções comuns e específicas do Analysis Services e Mondrian
Dentre as 104 (cento e quatro) funções MDX comuns, existem funções
que são sobrecarregadas, ou seja, mais de uma função com o mesmo nome,
porém com argumentos (i.e., parâmetros) diferentes. Dessa forma, quando
uma função MDX é utilizada em uma consulta, o servidor determina a função a
ser chamada a partir dos tipos de dados e do número de argumentos
fornecidos. Por exemplo, a função MDX Ancestor, quanto à sintaxe, tem duas
formas de utilização. A primeira forma é “Ancestor(Member_Expression,
Level_Expression)”, cujo o segundo argumento é uma expressão de nível, e a
segunda forma da sintaxe é “Ancestor(Member_Expression, Distance)”, sendo
o segundo argumento uma distância representada por um valor numérico. A
partir desta análise, constatou-se que o Mondrian tem mais funções
sobrecarregadas (17 ou 16,35%) que o Analysis Services (15 ou 14,42%) - ver
Gráfico 4.2. As funções sobrecarregadas do Analysis Service e Mondrian são
destacadas em amarelo na no APÊNDICE H.
42
Gráfico 4.2 - Funções sobrecarregadas do Analysis Services e Mondrian
Dado que existem funções sobrecarregadas em ambos os servidores,
foi necessário contar, a partir das 104 (cento e quatro) funções com o mesmo
nome, quantas sintaxes diferentes existem para estas funções. Neste sentido,
os totais foram: 128 (cento e vinte e oito) sintaxes para o Analysis Services e
132 (cento e trinta duas) para o Mondrian. Estes totais podem ser conferidos
nas colunas dois e três do quadro apresentado no APÊNDICE F. É importante
destacar que apenas a sintaxe básica das funções (i.e., parâmetros
obrigatórios) foi considerada para realizar as referidas contagens. Uma vez que
a quantidade de sintaxes básicas do Analysis Services (128) é diferente do
Mondrian (132), também foi necessário identificar a quantidade de sintaxes
exatamente iguais e aquelas que eram específicas de cada um dos servidores.
Neste caso, os totais foram: 122 (cento e vinte e duas) sintaxes iguais, 6 (seis)
sintaxes específicas do Analysis Services e 10 (dez) exclusivas do Mondrian.
Estes totais podem ser consultados a partir das colunas seis, sete e oito do
quadro apresentado no APÊNDICE F. O Gráfico 4.3 resume esta discussão.
43
Gráfico 4.3 - Quantidade de sintaxes nos servidores Analysis Services e Mondrian.
A proporção de sintaxes iguais (ver Gráfico 4.4) é um indicador
importante para uma análise comparativa de funções MDX nestes servidores.
Neste sentido, a partir da análise das 128 (cento e vinte e oito) sintaxes do
Analysis Service, constatou-se que as 122 (cento e vinte e duas) sintaxes
iguais perfazem 95,31%. Por sua vez, a partir das 132 (cento e trinta e duas)
sintaxes do Mondrian, constatou-se que as 122 (cento e vinte e duas) sintaxes
resultam em 92,42%. Além disso, a proporção de sintaxes exclusivas do
Analysis Services é 4,69% (i.e., 6/128), enquanto que a do Mondrian é 7,58%
(i.e., 10/132). Neste contexto, foram escritas 122 (cento e vinte e duas)
consultas MDX, as quais foram testadas utilizando a ferramenta TestMDX e
podem ser examinadas no APÊNDICE G. Na próxima seção, são apresentadas
as divergências de sintaxe do Mondrian e do Analysis Services.
128 132 122
6 10
0
20
40
60
80
100
120
140
Quantidade de sintaxes no
Analysis Services
Quantidade de sintaxes no Mondrian
Quantidade de sintaxes iguais
Quantidade de sintaxes exclusivas
do Analysis Services
Quantidade de sintaxes exclusivas
do Mondrian
44
Gráfico 4.4 - Sintaxes iguais e exclusivas no Analysis Services e Mondrian
4.2 FUNÇÕES COM SINTAXES EXCLUSIVAS No Analysis Services as funções AllMembers, CurrentMember,
DefaultMember, Dimension e Members só podem ser utilizadas com
hierarquias e níveis. Contudo, no Mondrian estas funções também podem ser
usadas em dimensões. Outras funções do Mondrian (e.g., ClosingPeriod,
Extract, IsEmpty, Levels e NonEmptyCrossJoin) são exclusivas devido ao tipo
de argumento utilizado na sintaxe (i.e., membro, cadeia de caracteres,
dimensão, expressão numérica ou conjunto – ver Quadro 4.1). Da mesma
forma, no Analysis Services, existem funções (ver Quadro 4.2) com sintaxes
exclusivas (e.g., CoalesceEmpty, Count, Descendants, Extract,
NonEmptyCrossjoin). Ressalta-se que as funções Extract e
NonEmptyCrossJoin possuem sintaxes exclusivas tanto no Analysis Services
quando no Mondrian.
Quadro 4.1 – Sintaxes exclusivas do Mondrian
Funções do Mondrian com sintaxe divergente
<Dimension>.AllMembers
ClosingPeriod(<Member>)
<Dimension>.CurrentMember
<Dimension>.DefaultMember
<Dimension>.Dimension
Extract(<Set>, <Dimension>[, <Dimension>...])
IsEmpty(<Numeric Expression>)
Levels(<String>)
<Dimension>.Members
NonEmptyCrossJoin(<Set>, <Set>)
45
Quadro 4.2 - Sintaxes exclusivas do Analysis Services
Funções do Analysis Services com sintaxe divergente
CoalesceEmpty(String_Expression1 [ ,String_Expression2,...n] )
Dimensions.Count
Hierarchy_Expression.Levels.Count
Descendants(Set_Expression [ , Level_Expression [ ,Desc_Flag ] ] )
Extract(Set_Expression, Hierarchy_Expression1 [,Hierarchy_Expression2, ...n] )
NonEmptyCrossjoin(Set_Expression1 [ ,Set_Expression2,...] [,Count ] )
4.3 DIVERGÊNCIAS ENCONTRADAS COM A AJUDA DE TESTMDX Analisando os resultados dos testes executados com a ferramenta
TestMDX, constatou-se que a função StrToSet não pode ser executada no
Mondrian utilizando-se apenas a sintaxe básica (obrigatória). Testada a sintaxe
básica no Mondrian, o servidor retornou a informação de que esta função deve
ter pelo menos dois argumentos. Ou seja, de acordo com a documentação do
Mondrian a sintaxe da função é “StrToSet(<String>[, <Dimension>...])”,
entretanto o segundo argumento da função (i.e., <Dimension>), que deveria ser
opcional, é obrigatório, de modo que a sintaxe básica mais apropriada para o
Mondrian é “StrToSet(<String>,<Dimension>)”.
Da mesma forma, constatou-se que a função StrToTuple não pode ser
excutada no Mondrian utilizado-se apenas a sintaxe básica. Testada a sintaxe
básica no Mondrian, o servidor retornou a informação de que esta função deve
ter pelo menos dois argumentos. Ou seja, na documentação do Mondrian, a
sintaxe da função StrToTuple é “StrToTuple(<String>)”. Embora nesta sintaxe
tem-se apenas um argumento (i.e., <String>), é necessário informar um
segundo argumento (i.e., <Dimension>) que corresponde a uma dimensão do
cubo. Dessa forma, no Mondrian, a sintaxe básica mais apropriada para esta
função é “StrToTuple(<String>,<Dimension>)”.
Além das diferenças de sintaxes, o Analysis Services e o Mondrian
também apresentam divergências quanto à forma de ordenar membros nos
resultados de consultas usando as funções DrillDownLevelBottom e
DrillDownLevelTop. Conforme análise dos resultados dos testes, constatou-se
que apesar de utilizar o mesmo DW e cubo de dados, nestas funções os
membros são recuperados em ordens distintas dependendo do servidor
utilizado na consulta. Por exemplo, usando a função DrillDownLevelBottom no
46
Analysis Services, a ordem dos membros é descendente, porém no Mondrian
não há uma ordem específica (i.e., ascendente ou descendente) dos membros.
Já na função DrillDownLevelTop, o Analysis Services recupera membros em
ordem ascendente, enquanto no Mondrian a ordem é descendente. Dessa
forma, utilizando estas funções, os resultados das consultas são divergentes
nestes servidores.
Outras divergências quanto aos resultados das consultas ocorrem nas
funções IsAncestor, IsEmpty, IsGeneration, IsLeaf, IsSibling que retornam os
operadores lógicos “true” ou “false”. No Analysis Services, estas funções
apresentam estes operadores como “True” ou “False”, porém no Mondrian
estes são apresentados como “true” e “false”. Embora a semântica destes
operadores lógicos seja a mesma nos dois servidores, nota-se uma diferença
no primeiro caractere de cada um destes operadores. Dessa forma,
dependendo do servidor utilizado para a consulta, aplicações clientes obterão
resultados que precisam ser padronizados antes de serem analisados. No
próximo capítulo, são apresentadas as considerações finais e também
propostas para trabalhos futuros.
47
5. CONCLUSÕES
O objetivo deste capítulo é apresentar as considerações finais sobre os
principais conceitos e tópicos existentes neste trabalho, bem como os objetivos
que foram transformados em contribuições e algumas indicações para
trabalhos futuros.
5.1 CONSIDERAÇÕES FINAIS A informação é um insumo relevante para o processo de tomada de
decisão. Neste sentido, a utilização de DW, ferramentas OLAP e a linguagem
MDX têm contribuído significativamente com este processo. Por isso, qualquer
divergência nas funções MDX, em relação aos servidores OLAP, pode
comprometer os resultados das consultas e, consequentemente, a qualidade
da decisão.
Apesar da linguagem MDX ser usada pela maioria dos servidores OLAP,
esta não é um padrão de direito. Dessa falta de padrão, surgem os problemas
de divergências nas funções MDX, visto que não há obrigatoriedade dos
servidores OLAP aderirem, por completo, a uma especificação de outro
fabricante. Dessa forma, cada fornecedor OLAP pode estender a sintaxe MDX
adicionando operadores e funções, inclusive com parâmetros adicionais, ou até
mesmo pode tornar obrigatório o uso de parâmetros que são opcionais na
sintaxe de outros servidores. Estas divergências nas funções MDX podem
dificultar a elaboração de consultas em diferentes servidores OLAP. Então,
torna-se muito importante identificar e tornar conhecidas estas diferenças. Por
esse motivo, justifica-se a realização deste trabalho.
Nesta dissertação foi apresentada uma estratégia e a ferramenta
TestMDX para realizar uma análise comparativa de funções MDX nos
servidores Analysis Services e Mondrian. Contudo, este método, assim com a
ferramenta, podem ser estendidos para uma análise comparativa em outros
servidores OLAP à MDX.
48
5.2 TRABALHOS FUTUROS Uma proposta para trabalhos futuros é a realização de um mapeamento
das divergências de funções MDX abrangendo outros servidores OLAP. Outra
proposta é uma implementação em Java para solucionar problemas (e.g.,
necessidade de reescrever consultas, migração de servidor OLAP) causados
por divergência de funções MDX entre servidores OLAP, ou seja, tratar
problemas de heterogeneidade da sintaxe MDX.
49
REFERÊNCIAS
[1] R. Kimball and M. Ross, The Data Warehouse Toolkit: The Complete Guide to Dimensional Modeling., 2nd ed. John Wiley & Sons, 2002, p. 464.
[2] Carl Nolan. Intoduction to Multidimensional Expressions (MDX). Microsoft Corporation, August 1999.
[3] XMLA - XML for Analysis Services. What is XML for Analysis Services (XMLA)?. Disponível em <http://news.xmlforanalysis.com/what-is-xmla.html > Acessado em 15/05/2012.
[4] W3C. Web Services Activity. Disponível em <http://www.w3.org/2002/ws/> Acessado em 16/05/2012.
[5] W. H. Inmon, Building the data WareHouse, 2nd ed. New York: John Wiley & Sons, 1996, p. 401.
[6] R. Kimball and M. Ross, The Data WareHouse Toolkit, 1st ed. New York: John Wiley & Sons, 1996, p. 464.
[7] R. N. Fidalgo, “Uma Infra-Estrutura para Integração de Modelos, Esquemas e Serviços Multidimensionais e Geográficos.,” Biblioteca Digital de Teses e Dissertações da UFPE, 2005.
[8] S. LIN and D. BROWN, “An outlier-based data association method for linking criminal incidents,” Decision Support Systems, vol. 41, no. 3, pp. 604-615, Mar. 2006.
[9] C. M. Tanure, “Uma Arquitetura de Software para Descoberta de Regras de Associação Multidimensional , Multinível e de Outliers em Cubos OLAP: um Estudo de Caso com os Algoritmos APriori e FP-Growth,” Universidade Federal de Pernambuco, 2010.
[10] E. Thomsen, OLAP Solutions: Building Multidimensional Information Systems. John Wiley & Sons, 1997.
[11] F. R. Paim, “Uma Metodologia para Análise de Requisitos em Sistemas Data Warehouse.,” Universidade Federal de Pernambuco, 2003.
[12] Microsoft. MDX Function Reference. Disponível em <
http://msdn.microsoft.com/en-us/library/ms145970.aspx> Acessado em 16/03/2012.
50
[13] Sallam, Rita L.; Richardson, James; hagerty, John e Hostmann, Bill. Magic Quadrant for Business Intelligence Platforms. Disponível em: <http://www.gartner.com/id=1531017> Acesso em: 20/02/2013 de outubro de 2012.
51
ANEXO A - SCRIPT PARA CARGA DE DADOS NA BASE FOODMART DO
MYSQL
Este anexo contém o script necessário para efetuar carga de dados do
DW FoodMart.
java -cp "mondrian.jar;log4j-1.2.8.jar;commons-logging-1.0.4.jar;eigenbase-
xom.jar;eigenbase-resgen.jar;eigenbase-properties.jar;mysql-connector-java-5.1.10.jar"
mondrian.test.loader.MondrianFoodMartLoader -verbose -tables -data -indexes -
jdbcDrivers=com.mysql.jdbc.Driver -inputFile=FoodMartCreateData.sql -
outputJdbcURL="jdbc:mysql://localhost/foodmart?user=foodmart&password=foodmart"
52
APÊNDICE A - CRIANDO A BASE DE DADOS FOODMART NO MYSQL
Este apêndice apresenta o processo de criação da base de dados
foodmart no banco de dados MySQL em computadores com sistema
operacional Windows.
Pré-requisitos:
Java Development Kit (JDK)
Arquivo mondrian-3.2.1.13885.zip (disponível em
http://sourceforge.net/projects/mondrian/files/mondrian/mondrian
-3.2.1.13885/)
Arquivo mysql-connector-java-5.1.10.jar (disponível em
http://dev.mysql.com/downloads/connector/j/ )
MySQL Instalado
Antes de executar os procedimentos para instalação da base foodmart
deve-se criar uma base de dados de nome foodmart no MySQL e também criar
o usuário foodmart com a senha foodmart. Utilizando-se de algum outro usuário
e senha para conectar-se à base de dados será preciso modificar os campos
user e password no script de criação e carga de dados. O usuário deve ter
permissão de administrador para a base de dados foodmart.
Na pasta que foi descompactada existe uma subpasta pasta de nome
lib. Dentro desta existe um auquivo de nome mondrian.war que também deve
ser decompactado. Dentro deste arquivo existe uma pasta de nome lib (Figura
A.1) e é nesta pasta que estão os arquivos que devem ser copiados para
c:\install_foodmart. Os arquivos são:
mondrian.jar
log4j-1.2.8.jar
commons-logging-1.0.4.jar
eigenbase-xom.jar
eigenbase-resgen.jar
eigenbase-properties.jar
53
Figura A.1 - Arquivos da pasta lib dentro do arquivo mondrian.war
Dentro da pasta C:\mondrian-3.2.1.13885\demo existe o arquivo
FoodMartCreateData.sql e este também deve ser copiado para a pasta
C:\install_foodmart.
Tendo baixado o connector Java para MySQL (i.e., mysql-connector-
java-5.1.10.jar) deve-se copiar este arquivo para a pasta
c:\install_foodmart.Também copiar o arquivo mondrian-
3.2.1.13885\demo\FoodMartCreateData.sql (Figura A.2) para a pasta
C:\install_foodmart.
Figura A.2 - Arquivo FoodMartCreateData.sql para carga de dados da base FoodMart
Figura A.3 - Pasta de instalação com arquivos copiados
54
Pode-se copiar e colocar o script (Código A.1) em um arquivo de nome
INSTALL.BAT e gravar na pasta c:\install_foodmart. Assim após modificar o
script caso seja necessário, basta executar no prompt o comando
INSTALL.BAT. Este script deve ser digitado ou copiado em apenas uma linha,
ou seja, não deve haver quebra de linha entre estes comandos, caso contrário
haverá falha na execução.
Digite cd C:\install_foodmart no prompt de comando (para acessar a
pasta com os arquivos) e em seguida execute o script (Código A.1) para iniciar
a instalação da base foodmart no MySQL. É importante observar que pode ser
necessário fazer alguma alteração no script, em caso de versões diferentes dos
arquivos. Após a conclusão da criação da base de dados foodmart a pas
c:\install_foodmart pode ser deletada. Aguarde o final da execução do script.
Após a conclusão a posta c:\install_foodmart pode ser eliminada.
Código A.1 - Script para carga de dados na base foodmart do Mysql
java -cp "mondrian.jar;log4j-1.2.8.jar;commons-logging-1.0.4.jar;eigenbase-
xom.jar;eigenbase-resgen.jar;eigenbase-properties.jar;mysql-connector-java-5.1.10.jar"
mondrian.test.loader.MondrianFoodMartLoader -verbose -tables -data -indexes -
jdbcDrivers=com.mysql.jdbc.Driver -inputFile=FoodMartCreateData.sql -
outputJdbcURL="jdbc:mysql://localhost/foodmart?user=foodmart&password=foodmart"
55
APÊNDICE B - CONECTANDO O ANALYSIS SERVICES COM O MYSQL
1. Instalando o MySQL Connector/NET.
A instalação deve ser feita em um computador que já tenha o Visual
Studio funcionando. O objetivo desta instalação é possibilitar a conexão do
Analysis Services Services e do Visual Studio ao banco de dados MySQL.
Dessa forma é possível criar cubos OLAP utilizando fonte de dados (i.e.,
DataSource) do MySQL. Para instalar é necessário baixar o MySQL
Connector/NET disponível no site
http://dev.mysql.com/downloads/connector/net/ . É importante fechar a
ferramenta Visual Studio antes de instalar o conector. Execute o arquivo
baixado para iniciar a instalação e Escolha o tipo de instalação completa
(Figura B.1).
Figura B.1 - Iniciando a instalação do MySQL Connector/NET
56
2. Configurando a conexão do MySQL no Visual Studio
Crie um novo projeto no Visual Studio e clique com o botão direito do
mouse sobre Data Sources e selecione New Data Sources. Para o provider
escolha MySQL Data Provider. Clique no botão “OK” e informe os dados
usuários e senha e o nome da base de dados foodmart do MySQL. Este
usuário deve ter permissão de acesso à base foodmart. Na tela Connection
Manager clique em All e mude a propriiedade SQL Server Mode para “true”. As
figuras a seguir mostram etapas para a configuração.
Figura B.2 - Data Source com MySQL Data Provider
Figura B.3 - Parâmetros para conexão com a base foodmart do MySQL
57
Figura B.4 - Modificando valor do parâmetro "Sql Server Mode"
Figura B.5 - Testando a conexão com o MySQL
Figura B.6 - Definindo credenciais de acesso para o Data Source
58
Figura B.7 - Finalizando a instalação
Após estes procedimentos a base estará acessível e os dados
disponíveis para criação de cubos (Figura B.8). O processo de criação do cubo
segue o procedimento normal utilizado com outras fontes de dados.
Figura B.8 - Data Source criado para foodmart
Figura B.9 - Seleção de tabelas para Data Source View
59
Figura B.10 - Data Source View com tabelas de foodmart
É preciso criar uma regra de acesso e selecionar os usuários ou grupo
de usuários que podem fazer consultas no cubo através de XMLA. Neste
projeto do cubo Sales foi criada uma regra denominada XMLA_Access e foi
liberado o acesso para todos os usuários.
Figura B.11 - Regra XMLA_Access (Tela 1)
Figura B.12 - Regra XMLA_Access (Tela 2)
60
APÊNDICE C - CONFIGURAÇÃO DO IIS PARA ACESSO HTTP XMLA
Aplicações clientes não podem usar as bibliotecas de cliente do
Analysis Services Services (e.g., um aplicativo Java executado em um servidor
Linux). Neste caso usase-se o SOAP e o XML/A em uma conexão HTTP direta
a uma instância do Analysis Services Services. A seguir é a presentado o
processo de configuração do acesso XMLA para o Analysis Services.
A maneira mais fácil de instalar o IIS é através da opção Painel de
Controle\Programas\Ativar desativar recursos do Windows (Figura C.1). Para
fins deste trabalho, foi utilizado o IIS na versão 7. Este servidor foi configurado
para responder solicitações na porta 80.
Figura C.1 - Iniciando instalação do IIS
Os recursos mínimos que devem ser instalados estão localizados na
pasta do Internet Information Services, são eles: Ferramentas de Gestão, web.
Extensibilidade NET, ASP.NET, extensões ISAPI, Autenticação básica e
Windows Autenticação (ver Figura C.2).
Figura C.2 - Configurações mínimas para o IIS
61
Encerrada a instalação do IIS, deve-se criar um pool de aplicativos
para a aplicação. Para isso é preciso acessar a tela de configuração do IIS (ver
Figura C.2). Isso pode ser feito de duas formas: a primeira é executando o
comando inetmgr.exe (através do Prompt de Comando do Windows) e a
segunda é clicar com o botão direito do mouse sobre o ícone meu computador
e selecionar a opção gerenciar, em seguida selecionar serviços e aplicativos e
o gerenciador de serviços de informações da internet (ver Figura C.3). Depois
disso basta posionar o mouse sobre Pools de Aplicativos e Adicionar pool de
aplicativos, e fornecer um nome, por exemplo, olap (ver Figura C.4).
Figura C.3 - Iniciando o gerenciador do IIS
Figura C.4 - Adicionando pool de aplicativos no IIS
62
É preciso copiar alguns arquivos que serão a base do website que
fornece o acesso HTTP XMLA. Estes arquivos estão localizados na pasta onde
foi instalado o servidor SQL (e.g. C:\Program Files\Microsoft SQL
Server\MSAS10.MSSQLSERVER\OLAP\bin\isapi) na subpasta \OLAP\bin\isapi
(Figura C.5). Basta copiar todos os arquivos desta pasta e colar em uma nova
pasta sob o diretório raiz do site padrão.
Figura C.5 - Copiando arquivos do mecanismo XMLA
Para encontrar a pasta de destino para estes arquivos copiados deve-
se clicar sobre o nome do site no gerenciador de configuração e pressionando
Explorar. Criar uma nova pasta chamada olap e colar os arquivos copiados.
São estes arquivos que fornecem o mecanismo do XMLA (ver Figura C.6).
Figura C.6 - Colando arquivos copiados na pasta olap do site padrão IIS
Também deve-se ter certeza de que o usuário que executa o serviço
IIS tem permissão para ler os arquivos na pasta. Verifique as permissões indo
até a seção segurança das propriedades na pasta pai (a raiz da web). Se as
permissões não estiverem corretas o servidor emite uma mensagem de erro
informando que os arquivos não podem ser encontrados ou não há permissão
de acesso para os arquivos.
63
Expanda o site da Web padrão, pressionar atualizar e localize a pasta
olap (Figura C.7). Posicione o mouse sobre a pasta olap e com botão direito
do mouse e pressione a opção Converter para Aplicativo (Figura C.8). Após a
conversão será exibida uma tela conforme mostra a Figura C.9.
Figura C.7 - Pasta olap selecionada para conversão de aplicativo
Figura C.8 - Converter para Aplicativo
64
Figura C.9 - Concluindo conversão para aplicativo no IIS
Também é preciso adicionar um manipulador para para todas as DLLs
(*.dll) do site. Selecione a pasta olap e do IIS pressionar Configurações
Mapeamentos (Figura C.10). No lado direito da tela, encontra-se um link
Adicionar mapa de script. Basta clique no link e em seguida preencher os
campos conforme mostra a Figura C.11. Feito isso deve-se verificar se o
acesso HTTP XMLA já está funcionando.Para isso basta digitar a url
http://localhost/olap/msmdpump.dll em um navegador web (Figura C.12).
Figura C.10 - Manipulador para dlls do site
65
Figura C.11 - Mapeamento de Script
Figura C.12 - Teste de acesso HTTP XMLA
66
APÊNDICE D - INSTALAÇÃO E CONFIGURAÇÃO DO MONDRIAN
Para instalar o Mondrian é preciso atender aos seguintes pré-
requisitos:
Java Development Kit (JDK)
Apache Tomcat (com driver JDBC no diretório tomcat\lib)
Arquivo mondrian-3.2.1.13885.zip (disponível em
http://sourceforge.net/projects/mondrian/files/mondrian/mondrian
-3.2.1.13885/ )
Ter baixado o arquivo mysql-connector-java-5.1.10.jar
(disponível em http://dev.mysql.com/downloads/connector/j/ )
O promeiro passo é descompactar o arquivo do Mondrian baixado:
mondrian-3.2.1.13885.zip. Por exemplo, se descompactado na raiz do diver C:\,
a pasta do Mondrian será C:\mondrian-3.2.1.13885 e o conteúdo da pasta
semelhante a mostrado na Figura D.1.
Figura D.1 - Arquivos do Mondrian descompactados
Em seguida copiar o arquivo C:\mondrian-
3.2.1.13885\lib\mondrian.war, para a pasta tomcat\webapps. Uma vez que este
arquivo é copiado e o tomcat está sendo executado, automaticamente o tomcat
irá criar uma pasta e descompactar o arquivo mondrian.war dentro da pasta
67
tomcat\webapps, conforme mostra a Figura D.2. Também deve ser copiado
para o servidor tomcat o arquivo mysql-connector-java-5.1.10.jar (jdbc do
MySQL) para a pasta tomcat\lib (ver Figura D.3).
Figura D.2 - Pasta do Mondrian criada pelo arquivo mondrian.war no servidor Tomcat
Figura D.3 - Conector jdbc MySQL na pasta lib do Tomcat
A especificação XMLA permite a um provedor de XMLA ter
múltiplas fontes de dados, mas alguns clientes, especialmente os
com base em ADOMD.NET, só pode se conectar à primeira fonte de dados
declarada. Portanto, recomenda-se que utilize apenas uma fonte de dados de
origem, contendo vários catálogos, se necessário. Considera-se nesta etapa de
configuração que a fonte de dados JDBC já está instalada. Editar o arquivo
datasource.xml que fica dentro da pasta tomcat\webapps\mondrian\WEB-INF.
Neste exemplo (ver Quadro D.1) foi utilizado o usuário root com a senha mysql.
68
Quadro D.1 - Arquivo datasource.xml do Mondrian configurado para conectar MySQL
A seguir são descritos alguns dos tags do arquivo datasource.xml,
necessários para configurar a conexão do Mondrian com as fontes de dados:
DataSourceName: refere-se ao nome da fonte de dados para o
Mondrian, este nome é utlizado na url de conexão com o servidor.
URL: a URL que será usado para se conectar à fonte de dados OLAP
via definição do Datasource.
DataSourceInfo: contém os detalhes relacionados com o prestador do
serviço XMLA, como provedor, JDBC DataSource, usuário, senha, tipo
de driver.
Catalog name: refere-se ao arquivo que contém definições relacionadas
com as dimensões, hierarquias e cubos que serão utilizadas. Este é um
arquivo tipo xml deve estar dentro da pasta WEB-INF/queries/ do
Mondrian. Por exemplo, o arquivo FoodMart.xml, utilizado nesta
dissertação.
<?xml version="1.0"?>
<DataSources> <DataSource>
<DataSourceName>Provider=Mondrian;DataSource=MondrianFoodMart;</
DataSourceName> <DataSourceDescription>Mondrian FoodMart
Data Warehouse</DataSourceDescription>
<URL>http://localhost:8080/mondrian/xmla</URL>
<ProviderName>Mondrian</ProviderName>
<ProviderType>MDP</ProviderType>
<AuthenticationMode>Unauthenticated</AuthenticationMode>
<Catalogs>
<Catalog name="FoodMart">
<DataSourceInfo>
Provider=mondrian;
Jdbc=jdbc:mysql://localhost/foodmart; JdbcUser=root;
JdbcPassword=mysql; JdbcDrivers=com.mysql.jdbc.Driver
</DataSourceInfo>
<Definition> /WEB-INF/queries/FoodMart.xml
</Definition>
</Catalog>
</Catalogs>
</DataSource></DataSources>
69
Outros arquivos do Mondriam que estão na pasta
tomcat\webapps\mondrian\WEB-INF\queries, também precisam ser
modificados são eles: fourhier.jsp, mondrian.jsp, colors.jsp e arrows.jsp. Os
detalhes das modificações destes e outros arquivos podem ser observados a
seguir.
Localize as seguintes linhas:
<jp:mondrianQuery id="query01"
jdbcDriver="sun.jdbc.odbc.JdbcOdbcDriver"
jdbcUrl="jdbc:odbc:MondrianFoodMart" catalogUri="/WEB-
INF/queries/FoodMart.xml">
Modifique para
<jp:mondrianQuery id="query01"
jdbcDriver="com.mysql.jdbc.Driver"
jdbcUrl="jdbc:mysql://localhost/foodmart?user=foodmart&password=foodma
rt" catalogUri="/WEB-INF/queries/FoodMart.xml">
Edite o arquivo testrole.jsp na tomcat\webapps\mondrian\web-
inf\queries, e localize as linhas
<jp:mondrianQuery id="query01"
jdbcDriver="sun.jdbc.odbc.JdbcOdbcDriver"
jdbcUrl="jdbc:odbc:MondrianFoodMart" catalogUri="/WEB-
INF/queries/FoodMart.xml" role="California manager">
Modifique para
<jp:mondrianQuery id="query01"
jdbcDriver="com.mysql.jdbc.Driver"
jdbcUrl="jdbc:mysql://localhost/foodmart?user=foodmart&password=foodma
rt" catalogUri="/WEB-INF/queries/FoodMart.xml" role="California
manager">
Edite o a arquivo tomcat\webapps\mondrian\web-inf\datasources.xml .
No tag <datasourceinfo> o datasource padrão deve ser a base de
dados foodmart
<DataSourceInfo>Provider=mondrian;Jdbc=jdbc:mysql://localhost/f
oodmart;JdbcUser=foodmart;JdbcPassword=foodmart;JdbcDrivers=com.mysql.
jdbc.Driver;</DataSourceInfo>
Edite o arquivo tomcat\webapps\mondrian\web-inf\mondrian.properties .
Localize e connectionstring property o padrão para a base de dados
foodmart deve ser com segue:
70
mondrian.test.connectString=Provider=mondrian;Jdbc=jdbc:mysql://localh
ost/foodmart;JdbcUser=foodmart;JdbcPassword=foodmart;JdbcDrivers=com.m
ysql.jdbc.Driver;Catalog=/WEB-INF/queries/FoodMart.xml;
Edite o arquivo tomcat\webapps\mondrian\web-inf\web.xml. Modifique
todas as ocorrências da string @mondrian.webapp.connectString@,
substituindo pelo detalhes para conexão com a base de dados foodmart.
Isto será necessário para o parâmetro de contexto ConnectString e as
secções de servlet MDXQueryServlet do arquivo, por exemplo:
<context-param>
<param-name>connectString</param-name>
<param-
value>Provider=mondrian;Jdbc=jdbc:mysql://localhost/foodmart;JdbcUser=
foodmart;JdbcPassword=foodmart;Catalog=/WEB-
INF/queries/FoodMart.xml;JdbcDrivers=com.mysql.jdbc.Driver;</param-
value>
</context-param>
<servlet>
<servlet-name>MDXQueryServlet</servlet-name>
<servlet-
class>mondrian.web.servlet.MdxQueryServlet</servlet-class>
<init-param>
<param-name>connectString</param-name>
<param-
value>Provider=mondrian;Jdbc=jdbc:mysql://localhost/foodmart;JdbcUser=
foodmart;JdbcPassword=foodmart;JdbcDrivers=com.mysql.jdbc.Driver;Catal
og=/WEB-INF/queries/FoodMart.xml;</param-value>
</init-param>
</servlet>
Testando o acesso ao Mondrian OLAP Server
Após todas as modificações serem efetuadas nestes arquivos já é
possível acessar o Mondrian através de um navegador (ver Figura D.4 e Figura
D.5) e testar o funcionamento do Mondrian com a base de dados foodmart do
MySQL.
71
Figura D.4 - Navegador acessando o Mondrian OLAP Server
Figura D.5 - Mondrian OLAP Server exibindo dados da base foodmart
72
APÊNDICE E - COMPARAÇÃO DE FUNÇÕES MDX
Neste apêndice tem-se um quadro destacando em amarelo as funções
com o mesmo nome. Neste quadro, cada função destacada na coluna do
Analysis Services tem um número que corresponde a sua posição na coluna do
Mondrian e um contador das funções com o mesmo nome.
Analysis Services Mondrian
1. AddCalculatedMembers (4) - 1 1. Abs
2. Aggregate (5) - 2 2. Acos
3. AllMembers (6) - 3 3. Acosh
4. Ancestor (7) - 4 4. AddCalculatedMembers
5. Ancestors 5. Aggregate
6. Ascendants (11) - 5 6. AllMembers
7. Avg (17) - 6 7. Ancestor
8. Axis 8. Asc
9. BottomCount (18) - 7 9. AscB
10. BottomPercent (19) - 8 10. AscW
11. BottomSum (20) - 9 11. Ascendants
12. CalculationCurrentPass 12. Asin
13. CalculationPassValue 13. Asinh
14. CASE Statement 14. Atan2
15. Children (30) - 10 15. Atanh
16. ClosingPeriod (34) - 11 16. Atn
17. CoalesceEmpty (35) - 12 17. Avg
18. Correlation (36) - 13 18. BottomCount
19. Count (39) - 14 19. BottomPercent
20. Cousin (40) - 15 20. BottomSum
21. Covariance (41) - 16 21. CBool
22. CovarianceN (42) - 17 22. CByte
23. Crossjoin (43) - 18 23. CDate
24. Current 24. CDbl
25. CurrentMember (46) - 19 25. CInt
26. CurrentOrdinal 26. Cache
27. CustomData 27. CalculatedChild
28. DataMember (48) - 20 28. Caption
29. DefaultMember (56) - 21 29. Cast
30. Descendants (58) - 22 30. Children
31. Dimension (59) - 23 31. Chr
32. Dimensions (60) - 24 32. ChrB
33. Distinct (61) - 25 33. ChrW
73
34. DistinctCount 34. ClosingPeriod
35. Divide 35. CoalesceEmpty
36. DrilldownLevel (62) - 26 36. Correlation
37. DrilldownLevelBottom (63) - 27 37. Cos
38. DrilldownLevelTop (64) - 28 38. Cosh
39. DrilldownMember (65) - 29 39. Count
40. DrilldownMemberBottom 40. Cousin
41. DrilldownMemberTop 41. Covariance
42. DrillupLevel 42. CovarianceN
43. DrillupMember 43. Crossjoin
44. Error 44. CurrentDateMember
45. Except (66) - 30 45. CurrentDateString
46. Exists (67) - 31 46. CurrentMember
47. Extract (69) - 32 47. DDB
48. Filter (71) - 33 48. DataMember
49. FirstChild (72) - 34 49. Date
50. FirstSibling (74) - 35 50. DateAdd
51. Generate (81) - 36 51. DateDiff
52. Head (82) - 37 52. DatePart
53. Hierarchize (84) - 38 53. DateSerial
54. Hierarchy (85) - 39 54. DateValue
55. Iif (87) - 40 55. Day
56. Instr (93) - 41 56. DefaultMember
57. Intersect (96) - 42 57. Degrees
58. IsAncestor 58. Descendants
59. IsEmpty (98) - 43 59. Dimension
60. IsGeneration 60. Dimensions
61. IsLeaf 61. Distinct
62. IsSibling 62. DrilldownLevel
63. Item (99) - 44 63. DrilldownLevelBottom
64. KPIGoal 64. DrilldownLevelTop
65. KPIStatus 65. DrilldownMember
66. KPITrend 66. Except
67. KPIWeight 67. Exists
68. KPICurrentTimeMember 68. Exp
69. KPIValue 69. Extract
70. Lag (102) - 45 70. FV
71. LastChild (103) - 46 71. Filter
72. LastPeriods (104) - 47 72. FirstChild
73. LastSibling (105) - 48 73. FirstQ
74. Lead (106) - 49 74. FirstSibling
75. Leaves 75. Fix
76. Level (109) - 50 76. Format
77. Levels (110) - 51 77. FormatCurrency
74
78. LinkMember 78. FormatDateTime
79. LinRegIntercept (111) - 52 79. FormatNumber
80. LinRegPoint (112) - 53 80. FormatPercent
81. LinRegR2 (113) - 54 81. Generate
82. LinRegSlope (114) - 55 82. Head
83. LinRegVariance (115) - 56 83. Hex
84. LookupCube 84. Hierarchize
85. Max (119) - 57 85. Hierarchy
86. MeasureGroupMeasures 86. Hour
87. Median (120) - 58 87. IIf
88. Members (121) - 59 88. IPmt
89. MemberToStr 89. IRR
90. MemberValue 90. IS
91. Min (123) - 60 91. IS EMPTY
92. Mtd (127) - 61 92. IS NULL
93. Name (130) - 62 93. InStr
94. NameToSet 94. InStrRev
95. NextMember (131) - 63 95. Int
96. NonEmpty 96. Intersect
97. NonEmptyCrossjoin (132) - 64 97. IsDate
98. OpeningPeriod (135) - 65 98. IsEmpty
99. Order (136) - 66 99. Item
100. Ordinal (137) - 67 100. LCase
101. ParallelPeriod (140) - 68 101. LTrim
102. Parent (143) - 69 102. Lag
103. PeriodsToDate (145) - 70 103. LastChild
104. Predict 104. LastPeriods
105. PrevMember (149) - 71 105. LastSibling
106. Properties (150) - 72 106. Lead
107. Qtd (151) - 73 107. Left
108. Rank (154) - 74 108. Len
109. RollupChildren 109. Level
110. Root 110. Levels
111. SetToArray 111. LinRegIntercept
112. SetToStr (162) - 75 112. LinRegPoint
113. Siblings (164) - 76 113. LinRegR2
114. Stddev (170) - 77 114. LinRegSlope
115. StddevP (171) - 78 115. LinRegVariance
116. Stdev (172) - 79 116. Log
117. StdevP (173) - 80 117. Log10
118. StripCalculatedMembers (176) - 81 118. MIRR
119. StrToMember (178) - 82 119. Max
120. StrToSet (179) - 83 120. Median
121. StrToTuple (180) - 84 121. Members
75
122. StrToValue 122. Mid
123. Subset (182) - 85 123. Min
124. Sum (183) - 86 124. Minute
125. Tail (184) - 87 125. Month
126. This 126. MonthName
127. ToggleDrillState (192) - 88 127. Mtd
128. TopCount (193) - 89 128. NPV
129. TopPercent (194) - 90 129. NPer
130. TopSum (195) - 91 130. Name
131. TupleToStr (197) - 92 131. NextMember
132. Union (200) - 93 132. NonEmptyCrossJoin
133. UniqueName (201) - 94 133. Now
134. UnknownMember 134. Oct
135. Unorder (202) - 95 135. OpeningPeriod
136. UserName 136. Order
137. ValidMeasure (204) - 96 137. Ordinal
138. Value (205) - 97 138. PPmt
139. Var (206) - 98 139. PV
140. Variance (207) - 99 140. ParallelPeriod
141. VarianceP (208) - 100 141. ParamRef
142. VarP (209) - 101 142. Parameter
143. VisualTotals (210) - 102 143. Parent
144. Wtd (213) - 103 144. Percentile
145. Ytd (215) - 104 145. PeriodsToDate
146. Pi
147. Pmt
148. Power
149. PrevMember
150. Properties
151. Qtd
152. RTrim
153. Radians
154. Rank
155. Rate
156. Replace
157. Right
158. Round
159. SLN
160. SYD
161. Second
162. SetToStr
163. Sgn
164. Siblings
165. Sin
76
166. Sinh
167. Space
168. Sqr
169. SqrtPi
170. Stddev
171. StddevP
172. Stdev
173. StdevP
174. Str
175. StrComp
176. StripCalculatedMembers
177. StrReverse
178. StrToMember
179. StrToSet
180. StrToTuple
181. String
182. Subset
183. Sum
184. Tail
185. Tan
186. Tanh
187. ThirdQ
188. Time
189. TimeSerial
190. TimeValue
191. Timer
192. ToggleDrillState
193. TopCount
194. TopPercent
195. TopSum
196. Trim
197. TupleToStr
198. TypeName
199. UCase
200. Union
201. UniqueName
202. Unorder
203. Val
204. ValidMeasure
205. Value
206. Var
207. Variance
208. VarianceP
209. VarP
77
210. VisualTotals
211. Weekday
212. WeekdayName
213. Wtd
214. Year
215. Ytd
216. _CaseMatch
217. _CaseTest
78
APÊNDICE F - COMPARAÇÃO DA SINTAXE MDX
Neste apêndice tem-se um quadro no qual são destacadas em amarelo as sintaxes que são diferentes ou que não existem
em ambos os servidores (i.e., Analysis Services e Mondrian). Além disso, são contadas as sintaxes de cada um dos servidores
(considerando apenas os parâmetros obrigatórios), também as sintaxes iguais e exclusivas destes servidores.
Ordem
Quantidade de
sintaxes no Analysis Services
Quantidade de sintaxes
no Mondrian
Sintaxes Analysis Services Sintaxes Mondrian Quantidade de sintaxes
iguais
Quantidade de sintaxes
exclusivas do Analysis Services
Quantidade de sintaxes exclusivas
do Mondrian
1 1 1 AddCalculatedMembers(Set_Expression)
AddCalculatedMembers(<Set>) 1
2 1 1
Aggregate(Set_Expression [ ,Numeric_Expression ])
Aggregate(<Set>) 1
Aggregate(<Set>, <Numeric Expression>)
3 2 3
Hierarchy_Expression.AllMembers
<Dimension>.AllMembers
2
1 Level_Expression.AllMembers
<Hierarchy>.AllMembers
<Level>.AllMembers
4 2 2
Ancestor(Member_Expression, Level_Expression)
Ancestor(<Member>, <Level>) 2
Ancestor(Member_Expression, Distance)
Ancestor(<Member>, <Numeric Expression>)
5 1 1 Ascendants(Member_Expression)
Ascendants(<Member>) 1
6 1 1
Avg( Set_Expression [ , Numeric_Expression ] )
Avg(<Set>) 1
Avg(<Set>, <Numeric Expression>)
7 1 1
BottomCount(Set_Expression, Count [,Numeric_Expression])
BottomCount(<Set>, <Numeric Expression>, <Numeric Expression>) 1
BottomCount(<Set>, <Numeric Expression>)
8 1 1 BottomPercent(Set_Expression, Percentage, Numeric_Expression)
BottomPercent(<Set>, <Numeric Expression>, <Numeric Expression>) 1
9 1 1 BottomSum(Set_Expression, Value, Numeric_Expression)
BottomSum(<Set>, <Numeric Expression>, <Numeric Expression>) 1
10 1 1 Member_Expression.Children
<Member>.Children 1
79
11 1 2
ClosingPeriod( [ Level_Expression [ ,Member_Expression ] ] )
ClosingPeriod()
1
1 ClosingPeriod(<Level>)
ClosingPeriod(<Level>, <Member>)
ClosingPeriod(<Member>)
12 2 1
CoalesceEmpty( Numeric_Expression1 [ ,Numeric_Expression2,...n] )
CoalesceEmpty(<Value Expression>[, <Value Expression>...]) 1 1 0
CoalesceEmpty(String_Expression1 [ ,String_Expression2,...n] )
13 1 1
Correlation( Set_Expression, Numeric_Expression_y [ ,Numeric_Expression_x ] ) Correlation(<Set>, <Numeric Expression>)
1
Correlation(<Set>, <Numeric Expression>, <Numeric Expression>)
14 4 2
Dimensions.Count
Count(<Set>)
2 2
Hierarchy_Expression.Levels.Count
Count(<Set>, <Symbol>)
Count(Set_Expression [ , ( EXCLUDEEMPTY | INCLUDEEMPTY ) ] )
<Set>.Count
Set_Expression.Count
15 1 1 Cousin( Member_Expression , Ancestor_Member_Expression )
Cousin(<Member>, <Ancestor Member>) 1
16 1 1
Covariance(Set_Expression,Numeric_Expression_y [ ,Numeric_Expression_x ] )
Covariance(<Set>, <Numeric Expression>) 1
Covariance(<Set>, <Numeric Expression>, <Numeric Expression>)
17 1 1
CovarianceN(Set_Expression, Numeric_Expression_y [ ,Numeric_Expression_x ] ) CovarianceN(<Set>, <Numeric Expression>)
1
CovarianceN(<Set>, <Numeric Expression>, <Numeric Expression>)
18 1 1 Crossjoin(Set_Expression1 ,Set_Expression2 [,...n] )
Crossjoin(<Set>, <Set>) 1
19 1 2
Hierarchy_Expression.CurrentMember
<Dimension>.CurrentMember 1
1
<Hierarchy>.CurrentMember
20 1 1
Member_Expression.DataMember <Member>.DataMember
1
21 1 2
Hierarchy_Expression.DefaultMember
<Dimension>.DefaultMember 1
1
<Hierarchy>.DefaultMember
22 2 1
Descendants(Member_Expression [ , Level_Expression [ ,Desc_Flag ] ] )
Descendants(<Member>)
1 1
Descendants(Member_Expression [ , Distance [ ,Desc_Flag ] ] )
Descendants(<Member>, <Level>)
Descendants(Set_Expression [ , Level_Expression [ ,Desc_Flag ] ] )
Descendants(<Member>, <Level>, <Symbol>)
80
Descendants(Set_Expression [ , Distance [ ,Desc_Flag ] ] )
Descendants(<Member>, <Numeric Expression>)
Descendants(<Member>, <Numeric Expression>, <Symbol>)
Descendants(<Member>, <Empty>, <Symbol>)
23 3 4
Hierarchy_Expression.Dimension
<Dimension>.Dimension
3
1
Level_Expression.Dimension
<Hierarchy>.Dimension
Member_Expression.Dimension
<Level>.Dimension
<Member>.Dimension
24 2 2
Dimensions(Hierarchy_Number)
Dimensions(<Numeric Expression>) 2
Dimensions(Hierarchy_Name)
Dimensions(<String>)
25 1 1 Distinct(Set_Expression)
Distinct(<Set>) 1
26 1 1
DrilldownLevel(Set_Expression [ , Level_Expression ] )
DrilldownLevel(<Set>)
1
DrilldownLevel(Set_Expression [ , ,Index ] )
DrilldownLevel(<Set>, <Level>)
DrilldownLevel(<Set>, <Empty>, <Numeric Expression>)
27 1 1
DrilldownLevelBottom(Set_Expression, Count [ , Level_Expression [ ,Numeric_Expression ] ] ) DrilldownLevelBottom(<Set>, <Numeric Expression>)
1
DrilldownLevelBottom(<Set>, <Numeric Expression>, <Level>)
DrilldownLevelBottom(<Set>, <Numeric Expression>, <Level>, <Numeric Expression>)
DrilldownLevelBottom(<Set>, <Numeric Expression>, <Empty>, <Numeric Expression>)
28 1 1
DrilldownLevelTop(<set_expression>, <count> [,[<level_expression>] ,[<numeric_expression>][,INCLUDE_CALC_MEMBERS]]]) DrilldownLevelTop(<Set>, <Numeric Expression>)
1
DrilldownLevelTop(<Set>, <Numeric Expression>, <Level>)
DrilldownLevelTop(<Set>, <Numeric Expression>, <Level>, <Numeric Expression>)
DrilldownLevelTop(<Set>, <Numeric Expression>, <Empty>, <Numeric Expression>)
29 1 1
DrillDownMember(<set_expression1>, <set_expression2> [,[<target_hierarchy>]] [,[RECURSIVE][,INCLUDE_CALC_MEMBERS]]) DrilldownMember(<Set>, <Set>)
1
DrilldownMember(<Set>, <Set>, <Symbol>)
30 1 1
Except(Set_Expression1, Set_Expression2 [, ALL ] )
Except(<Set>, <Set>) 1
Except(<Set>, <Set>, <Symbol>)
31 1 1 Exists( Set_Expression1 , Set_Expression2 [, MeasureGroupName] )
Exists(<Set>, <Set>) 1
32 1 1 Extract(Set_Expression, Hierarchy_Expression1 [,Hierarchy_Expression2, ...n] ) Extract(<Set>, <Dimension>[, <Dimension>...])
1 1
81
33 1 1 Filter(Set_Expression, Logical_Expression )
Filter(<Set>, <Logical Expression>) 1
34 1 1
Member_Expression.FirstChild
<Member>.FirstChild
1
35 1 1 Member_Expression.FirstSibling
<Member>.FirstSibling 1
36 2 2
Generate( Set_Expression1 , Set_Expression2 [ , ALL ] )
Generate(<Set>, <Set>)
2
Generate( Set_Expression1 , String_Expression [ ,Delimiter ] )
Generate(<Set>, <Set>, <Symbol>)
Generate(<Set>, <String>)
Generate(<Set>, <String>, <String>)
37 1 1
Head(Set_Expression [ ,Count ] )
Head(<Set>) 1
Head(<Set>, <Numeric Expression>)
38 1 1
Hierarchize(Set_Expression [ , POST ] )
Hierarchize(<Set>) 1
Hierarchize(<Set>, <Symbol>)
39 2 2
Member_Expression.Hierarchy
<Level>.Hierarchy 2
Level_Expression.Hierarchy
<Member>.Hierarchy
40 1 1
IIf(Logical_Expression, Expression1 [HINT <hints>], Expression2 [HINT <hints>]) IIf(<Logical Expression>, <Tuple>, <Tuple>)
1
IIf(<Logical Expression>, <Dimension>, <Dimension>)
IIf(<Logical Expression>, <Hierarchy>, <Hierarchy>)
IIf(<Logical Expression>, <Level>, <Level>)
IIf(<Logical Expression>, <Logical Expression>, <Logical Expression>)
IIf(<Logical Expression>, <Member>, <Member>)
IIf(<Logical Expression>, <Numeric Expression>, <Numeric Expression>)
IIf(<Logical Expression>, <Set>, <Set>)
IIf(<Logical Expression>, <String>, <String>)
41 1 1
InStr([start, ]searched_string, search_string[, compare])
InStr(<String>, <String>)
1
42 1 1 Intersect(Set_Expression1 , Set_Expression2 [ , ALL ] )
Intersect(<Set>, <Set>, <Symbol>) 1
82
Intersect(<Set>, <Set>)
43 1 2
IsEmpty(Value_Expression)
IsEmpty(<String>) 1
1
IsEmpty(<Numeric Expression>)
44 3 3
Tuple_Expression.Item( Index )
<Tuple>.Item(<Numeric Expression>)
3
Set_Expression.Item(Index)
<Set>.Item(<Numeric Expression>)
Set_Expression.Item(String_Expression1 [ ,String_Expression2,...n])
<Set>.Item(<String> [, ...])
45 1 1 Member_Expression.Lag(Index)
<Member>.Lag(<Numeric Expression>) 1
46 1 1 Member_Expression.LastChild
<Member>.LastChild 1
47 1 1
LastPeriods(Index [ ,Member_Expression ] )
LastPeriods(<Numeric Expression>) 1
LastPeriods(<Numeric Expression>, <Member>)
48 1 1 Member_Expression.LastSibling
<Member>.LastSibling 1
49 1 1 Member_Expression.Lead( Index )
<Member>.Lead(<Numeric Expression>) 1
50 1 1 Member_Expression.Level
<Member>.Level 1
51 2 3
Hierarchy_Expression.Levels( Level_Number )
<Hierarchy>.Levels(<Numeric Expression>)
2
1 Hierarchy_Expression.Levels( Level_Name )
<Hierarchy>.Levels(<String>)
Levels(<String>)
52 1 1
LinRegIntercept(Set_Expression, Numeric_Expression_y [ ,Numeric_Expression_x ] ) LinRegIntercept(<Set>, <Numeric Expression>)
1
LinRegIntercept(<Set>, <Numeric Expression>, <Numeric Expression>)
53 1 1
LinRegPoint(Slice_Expression_x, Set_Expression, Numeric_Expression_y [ ,Numeric_Expression_x ] ) LinRegPoint(<Numeric Expression>, <Set>, <Numeric Expression>)
1
LinRegPoint(<Numeric Expression>, <Set>, <Numeric Expression>, <Numeric Expression>)
54 1 1
LinRegR2(Set_Expression, Numeric_Expression_y [ ,Numeric_Expression_x ] )
LinRegR2(<Set>, <Numeric Expression>) 1
LinRegR2(<Set>, <Numeric Expression>, <Numeric Expression>)
55 1 1
LinRegSlope(Set_Expression, Numeric_Expression_y [ ,Numeric_Expression_x ] ) LinRegSlope(<Set>, <Numeric Expression>)
1
LinRegSlope(<Set>, <Numeric Expression>, <Numeric Expression>)
56 1 1
LinRegVariance(Set_Expression, Numeric_Expression_y [ ,Numeric_Expression_x ] ] ) LinRegVariance(<Set>, <Numeric Expression>)
1
LinRegVariance(<Set>, <Numeric Expression>, <Numeric Expression>)
83
57 1 1
Max( Set_Expression [ , Numeric_Expression ] )
Max(<Set>) 1
Max(<Set>, <Numeric Expression>)
58 1 1
Median(Set_Expression [ ,Numeric_Expression ] )
Median(<Set>) 1
Median(<Set>, <Numeric Expression>)
59 3 4
Hierarchy_Expression.Members
<Dimension>.Members
3
1
Level_Expression.Members
<Hierarchy>.Members
Members(Member_Name)
<Level>.Members
Members(<String>)
60 1 1
Min( Set_Expression [ , Numeric_Expression ] )
Min(<Set>) 1
Min(<Set>, <Numeric Expression>)
61 1 1
Mtd( [ Member_Expression ] )
Mtd() 1
Mtd(<Member>)
62 4 4
Dimension_Expression.Name
<Dimension>.Name
4
Hierarchy_Expression.Name
<Hierarchy>.Name
Level_Expression.Name
<Level>.Name
Member_Expression.Name
<Member>.Name
63 1 1
Member_Expression.NextMember <Member>.NextMember
1
64 1 1 NonEmptyCrossjoin(Set_Expression1 [ ,Set_Expression2,...] [,Count ] )
NonEmptyCrossJoin(<Set>, <Set>) 1 1
65 1 1
OpeningPeriod()
1
OpeningPeriod( [ Level_Expression [ , Member_Expression ] ] )
OpeningPeriod(<Level>)
OpeningPeriod(<Level>, <Member>)
66 2 2
Order(Set_Expression, Numeric_Expression [ , { ASC | DESC | BASC | BDESC } ] ) Order(<Set>, <Value>, <Symbol>)
2
Order(Set_Expression, String_Expression [ , { ASC | DESC | BASC | BDESC } ] ) Order(<Set>, <Value>)
67 1 1 Level_Expression.Ordinal <Level>.Ordinal
1
84
68 1 1
ParallelPeriod( [ Level_Expression [ ,Index [ , Member_Expression ] ] ] )
ParallelPeriod()
1
ParallelPeriod(<Level>)
ParallelPeriod(<Level>, <Numeric Expression>)
ParallelPeriod(<Level>, <Numeric Expression>, <Member>)
69 1 1 Member_Expression.Parent
<Member>.Parent 1
70 1 1
PeriodsToDate( [ Level_Expression [ ,Member_Expression ] ] )
PeriodsToDate()
1 PeriodsToDate(<Level>)
PeriodsToDate(<Level>, <Member>)
71 1 1 Member_Expression.PrevMember
<Member>.PrevMember 1
72 1 1 Member_Expression.Properties(Property_Name [, TYPED])
<Member>.Properties(<String Expression>) 1
73 1 1
Qtd( [ Member_Expression ] )
Qtd() 1
Qtd(<Member>)
74 1 1
Rank(Tuple_Expression, Set_Expression [ ,Numeric Expression ] )
Rank(<Tuple>, <Set>)
1
Rank(<Tuple>, <Set>, <Numeric Expression>)
Rank(<Member>, <Set>)
Rank(<Member>, <Set>, <Numeric Expression>)
75 1 1 SetToStr(Set_Expression)
SetToStr(<Set>) 1
76 1 1 Member_Expression.Siblings
<Member>.Siblings 1
77 1 1
Stddev(Set_Expression [ ,Numeric_Expression ] )
Stddev(<Set>) 1
Stddev(<Set>, <Numeric Expression>)
78 1 1
StddevP(Set_Expression [ ,Numeric_Expression ] )
StddevP(<Set>) 1
StddevP(<Set>, <Numeric Expression>)
79 1 1
Stdev(Set_Expression [ ,Numeric_Expression ] )
Stdev(<Set>) 1
Stdev(<Set>, <Numeric Expression>)
80 1 1 StdevP(Set_Expression [ ,Numeric_Expression ] )
StdevP(<Set>) 1
85
StdevP(<Set>, <Numeric Expression>)
81 1 1 StripCalculatedMembers(Set_Expression)
StripCalculatedMembers(<Set>) 1
82 1 1 StrToMember(Member_Name [,CONSTRAINED] )
StrToMember(<String>) 1
83 1 1 StrToSet(Set_Specification [,CONSTRAINED] )
StrToSet(<String>[, <Dimension>...]) 1
84 1 1 StrToTuple(Tuple_Specification [,CONSTRAINED] )
StrToTuple(<String>) 1
85 1 1
Subset(Set_Expression, Start [ ,Count ] )
Subset(<Set>, <Numeric Expression>) 1
Subset(<Set>, <Numeric Expression>, <Numeric Expression>)
86 1 1
Sum( Set_Expression [ , Numeric_Expression ] )
Sum(<Set>) 1
Sum(<Set>, <Numeric Expression>)
87 1 1
Tail(Set_Expression [ ,Count ] )
Tail(<Set>) 1
Tail(<Set>, <Numeric Expression>)
88 1 1
ToggleDrillState(Set_Expression1,Set_Expression2 [ , RECURSIVE ] )
ToggleDrillState(<Set>, <Set>) 1
ToggleDrillState(<Set>, <Set>, <Symbol>)
89 1 1
TopCount(Set_Expression,Count [ ,Numeric_Expression ] )
TopCount(<Set>, <Numeric Expression>, <Numeric Expression>) 1
TopCount(<Set>, <Numeric Expression>)
90 1 1 TopPercent(Set_Expression, Percentage, Numeric_Expression)
TopPercent(<Set>, <Numeric Expression>, <Numeric Expression>) 1
91 1 1 TopSum(Set_Expression, Value, Numeric_Expression)
TopSum(<Set>, <Numeric Expression>, <Numeric Expression>) 1
92 1 1 TupleToStr(Tuple_Expression)
TupleToStr(<Tuple>) 1
93 1 1
Union(Set_Expression1, Set_Expression2 [,...n][, ALL])
Union(<Set>, <Set>) 1
Union(<Set>, <Set>, <Symbol>)
94 4 4
Dimension_Expression.UniqueName
<Dimension>.UniqueName
4
Hierarchy_Expression.UniqueName
<Hierarchy>.UniqueName
Level_Expression.UniqueName
<Level>.UniqueName
Member_Expression.UniqueName
<Member>.UniqueName
95 1 1 Unorder(Set_Expression)
Unorder(<Set>) 1
96 1 1 ValidMeasure(Tuple_Expression)
ValidMeasure(<Tuple>) 1
97 1 1 Member_Expression[.Value]
<Member>.Value 1
86
98 1 1
Var(Set_Expression [ ,Numeric_Expression ] )
Var(<Set>) 1
Var(<Set>, <Numeric Expression>)
99 1 1
Variance(Set_Expression [ ,Numeric_Expression ] )
Variance(<Set>) 1
Variance(<Set>, <Numeric Expression>)
100 1 1
VarianceP(Set_Expression [ ,Numeric_Expression ] )
VarianceP(<Set>) 1
VarianceP(<Set>, <Numeric Expression>)
101 1 1
VarP(Set_Expression [ ,Numeric_Expression ] )
VarP(<Set>) 1
VarP(<Set>, <Numeric Expression>)
102 1 1
VisualTotals(Set_Expression[,Pattern])
VisualTotals(<Set>) 1
VisualTotals(<Set>, <String>)
103 1 1
Wtd( [ Member_Expression ] )
Wtd() 1
Wtd(<Member>)
104 1 1
Ytd( [ Member_Expression ] )
Ytd() 1
Ytd(<Member>)
128 132 TOTAIS ISOLADOS 122 6 10
Total de funções do Analysis Services (122 + 6) = 128
Total de funções do Mondrian (122 + 10) = 132
87
APÊNDICE G - CONSULTAS TESTADAS COM A FERRAMENTA TESTMDX
ID da Consulta
Consulta MDX Função Testada
C1 SELECT AddCalculatedMembers( {[Measures].Profit} ) ON COLUMNS FROM [Sales]
AddCalculatedMembers
C2 WITH MEMBER [Measures].[Agregando alguns membros] AS 'AGGREGATE({[Product].[Product].[Product Family].[Drink], [Product].[Product].[Product Family].[Food] }) ' --agregando valores de membros SELECT {[Measures].[Agregando alguns membros]} ON 0 FROM [Sales]
Aggregate
C3 SELECT --obter todos os membros do nível ano da dimensão tempo {[Time].[Time].AllMembers} ON 0 FROM [Sales]
AllMembers
C4 SELECT --obter todos os membros do nível ano da dimensão tempo {[Time].[Time].[Year].AllMembers} ON 0 FROM [Sales]
AllMembers
C5
SELECT --obtem o ancestral do membro atual {Ancestor ( [Product].[Drink], 1)} ON 0 FROM [Sales]
Ancestor
C6 SELECT --obtem o ancestral do membro atual {Ancestor ( [Product].[Drink], [Product].[Product].[Product Family])} ON 0 FROM [Sales]
Ancestor
C7
SELECT --obter acendentes de Q1 do ano 1997 {Ascendants([Time].[1997].[Q1]) } on 0 FROM [Sales]
Ascendants
88
C8
WITH MEMBER [Measures].[media categoria] AS AVG({[Product].[Product].[Product Family].MEMBERS}) --Obter média de categorias SELECT [Measures].[media categoria] on 0 FROM [Sales]
Avg
C9
SELECT -- os dois piores resultados de vendas BOTTOMCOUNT({[Time].[Time].[Year].&[1997].CHILDREN}, 2,[Measures].[Unit Sales]) on 0 FROM [Sales]
BottomCount
C10
SELECT --obter percentuais mais baixos BottomPercent({[Product].[Product].[Product Family].Members}, 5, [Measures].[Unit Sales]) ON 0 FROM [Sales]
BottomPercent
C11 select --obter soma dos 5 valores mais baixos de vendas nas cidades BottomSum({[Product].[Product].[Product Family].Members}, 5, [Measures].[Unit Sales]) ON 0 from [Sales]
BottomSum
C12
SELECT -- filhos de um membro = conjunto [Time].[Time].[Year].&[1997].CHILDREN on 0 FROM [Sales]
Children
C13
SELECT --obter fechamento do período { ClosingPeriod() } on 0 FROM [Sales]
ClosingPeriod
C14 WITH MEMBER [Measures].[Test] AS COALESCEEMPTY([Measures].[Sales Count], 0), FORMAT_STRING='#,###' SELECT --Converte um valor de célula vazio a um valor zero {[Product].[Product].[Product Family].Members} ON 0 FROM [Sales]
CoalesceEmpty
89
C15
WITH MEMBER [Measures].[CorrCoef] AS 'FORMAT(CORRELATION([Time].[Quarter].Members, [Measures].[Unit Sales]), "####") ' SELECT --Retorna o coeficiente de correlação de pares x-y de valores avaliados em um conjunto. {[Measures].[CorrCoef]} ON COLUMNS FROM [Sales]
Correlation
C16
WITH MEMBER [Measures].[teste1] as 'Count([Time].[Year].members)' select [Measures].[teste1] on 0 from [Sales]
Count
C17 WITH MEMBER [Measures].[teste2] as '[Time].[Time].members.Count' select [Measures].[teste2] on 0 from [Sales]
Count
C18 SELECT --Retorna o membro filho com a mesma posição relativa de um membro pai como o membro filho especificado. { Cousin( [Time].[1998].[Q1].[1], [Time].[1997].[Q2] ) } ON 0 FROM [Sales]
Cousin
C19 with member [Measures].[CovarianceDemo] as 'Format(Covariance([Time].[Time].MEMBERS, [Measures].[Store Cost], [Measures].[Store Sales]),"####")' --Retorna a covariância de população dos pares x-y de valores avaliados em um conjunto, usando a fórmula de população polarizada (dividindo pelo número de pares x-y). select {[Measures].[CovarianceDemo]} ON COLUMNS from [Sales]
Covariance
C20 with member [Measures].[CovarianceNDemo] as 'Format(Covariance([Time].[Time].MEMBERS, [Measures].[Unit Sales], [Measures].[Store Sales]),"######")' --Retorna a covariância de população dos pares x-y de valores avaliados em um conjunto, usando a fórmula de população polarizada (dividindo pelo número de pares x-y). select {[Measures].[CovarianceNDemo]} ON COLUMNS from [Sales]
CovarianceN
90
C21
SELECT -- trabalhando com mais de uma dimensão por eixo CROSSJOIN({[Store].[Store].[Store Country].members}, {CROSSJOIN ({[Time].[Time].[Year]. MEMBERS}, {[Product].[Product].[Product Family].MEMBERS})}) on 0 FROM [Sales]
Crossjoin
C22 SELECT --Retorna o membro atual ao longo de uma hierarquia especificada durante a iteração. {[Measures].[Unit Sales]} ON COLUMNS, { [Product].[Product].Currentmember} ON ROWS FROM [Sales]
CurrentMember
C23 WITH MEMBER measures.InvidualQuota AS '[Product].[Drink].datamember' --Retorna o membro de dados gerado pelo sistema associado a um membro não-folha de uma dimensão. SELECT {[Measures].[Unit Sales],[Measures].InvidualQuota} ON COLUMNS, [Product].[Product].[Product Family].MEMBERS ON ROWS FROM [Sales]
DataMember
C24
SELECT --obter o membro padrão [Time].[Time].DEFAULTMEMBER ON 0 FROM [Sales]
DefaultMember
C25
SELECT -- todos os descendentes DESCENDANTS([Time].[1997]) on 0 FROM [Sales]
Descendants
C26 WITH member [Measures].[NomeDaDimensao] as '[Time].[1997].[Q1].Dimension.Name' --Retorna a hierarquia que contém um membro, nível ou hierarquia especificado. SELECT {[Measures].[NomeDaDimensao]} on COLUMNS FROM [Sales]
Dimension
C27 WITH member [Measures].[NomeDaDimensao] as '[Time].[Time].Dimension.Name' --Retorna a hierarquia que contém um membro, nível ou hierarquia especificado. SELECT {[Measures].[NomeDaDimensao]} on COLUMNS FROM [Sales]
Dimension
C28 WITH member [Measures].[NomeDaDimensao] as '[Time].[Time].[Year].Dimension.Name' --Retorna a hierarquia que contém um membro, nível ou hierarquia especificado. SELECT {[Measures].[NomeDaDimensao]} on COLUMNS FROM [Sales]
Dimension
91
C29 with member [Measures].[dim0] as 'Dimensions(0).Name' --obter o nome da hierarquia do membro especificado (Dimension junto com a função Name) select {[Measures].[dim0]} ON COLUMNS from [Sales]
Dimensions
C30 with member [Measures].[dim0] as 'Dimensions("[Product].[Product]").Name' --obter o nome da hierarquia do membro especificado (Dimension junto com a função Name) select {[Measures].[dim0]} ON COLUMNS from [Sales]
Dimensions
C31 SELECT --Encontrar tuplas duplicadas no conjunto especificada e manter apenas a primeira instância da tupla duplicada. {[Measures].[Unit Sales]} ON COLUMNS, DISTINCT([Time].[Time].[year].members) ON ROWS FROM [Sales]
Distinct
C32
SELECT -- detalhando um nível DRILLDOWNLEVEL( {[Time].[Time].[Year].members} ) on 0 FROM [Sales]
DrilldownLevel
C33
SELECT --Faz uma busca detalhada dos membros mais inferiores de um conjunto, em um nível especificado, para um nível abaixo. { [Measures].[Unit Sales] } on COLUMNS, DrillDownLevelBottom ([Time].[Time].Members, 2 ) on ROWS FROM [Sales]
DrilldownLevelBottom
C34 SELECT --Faz uma busca detalhada dos membros mais inferiores de um conjunto, em um nível especificado, para um nível abaixo. { [Measures].[Unit Sales] } on COLUMNS, DrillDownLevelTop ([Product].[Product].[Product Family].Members, 2, , 1 ) on ROWS FROM [Sales]
DrilldownLevelTop
C35 SELECT --Faz uma busca detalhada dos membros mais inferiores de um conjunto, em um nível especificado, para um nível abaixo. { [Measures].[Unit Sales] } on COLUMNS, DrillDownLevelTop ([Product].[Product].[Product Family].Members, 2 ) on ROWS FROM [Sales]
DrilldownLevelTop
92
C36
SELECT -- detalhando um membro NON EMPTY (DrilldownMember({[Product].[Product].[Product Family].[Drink]}, {[Product].[Product].[Product Family].[Drink]} ) ) on 0 FROM [Sales]
DrilldownMember
C37 select --Avalia dois conjuntos e remove as tuplas do primeiro conjunto e também existem no segundo, mantendo as duplicações (opcional). Except([Product].[Product].[Product Family].members, {[Product].[Product].[Product Family].[Drink]}) ON 0 from [Sales]
Except
C38 SELECT --Obter conjunto de tuplas do primeiro conjunto especificado que existe com uma ou mais tuplas do segundo conjunto especificado. {[Measures].[Unit sales]} ON COLUMNS, {exists([Time].[Time].[Year].[1997].[Q1] , [Time].[1997].[Q1].[1])} ON ROWS FROM [Sales]
Exists
C39 SELECT --Retorna o conjunto resultante da filtragem de um conjunto especificado com base em um critério de pesquisa. {[Measures].[Store Cost] } ON 0, { FILTER([Product].[Product].[Product Family].Members, [Measures].[Store Cost] > 20000 ) } ON 1 FROM [Sales]
Filter
C40
SELECT -- obter 1º. filho de um membro = member [Time].[Time].[Year].&[1997]. FIRSTCHILD on 0 FROM [Sales]
FirstChild
C41
SELECT --Retorna o primeiro filho do pai de um membro [Time].[Time].[Year].&[1997].FirstSibling ON 0 FROM [Sales]
FirstSibling
C42 SELECT --Aplica um conjunto a cada membro de outro conjunto e junta os conjuntos resultantes por união GENERATE ( [Time].[Time].[Year].MEMBERS, {[Time].[Time].[Year].[1997], [Time].[Time].[Year].[1997].children} ) on 0 FROM [Sales]
Generate
93
C43 WITH MEMBER MEASURES.GENERATESTRINGDEMO AS GENERATE( [Time].[Time].[Year].MEMBERS, [Time].[Year].CURRENTMEMBER.NAME) MEMBER MEASURES.GENERATEDELIMITEDSTRINGDEMO AS GENERATE( [Time].[Year].MEMBERS, [Time].[Year].CURRENTMEMBER.NAME, " AND ") SELECT {MEASURES.GENERATESTRINGDEMO, MEASURES.GENERATEDELIMITEDSTRINGDEMO} ON 0 FROM [Sales]
Generate
C44
select --Retorna o primeiro número especificado de elementos em um conjunto, mantendo as duplicações. {[Measures].[Unit Sales]} ON COLUMNS, Head([Product].[Food].Children) ON ROWS from [Sales]
Head
C45
SELECT -- hierarquizando um conjunto Hierarchize({[Time].[Time].[Quarter].members,[Time].[Time].[Month].members}) on 0 FROM [Sales]
Hierarchize
C46 with member [Measures].[HierarchyName] as '[Product].[Product].[Product Family].[Drink].Hierarchy.Name' --Retorna a hierarquia que contém um membro ou nível especificado. select {[Measures].[HierarchyName]} ON COLUMNS from [Sales]
Hierarchy
C47 with member [Measures].[HierarchyName] as '[Time].[Time].[Year].[1997].Hierarchy.Name' --Retorna a hierarquia que contém um membro ou nível especificado. select {[Measures].[HierarchyName]} ON COLUMNS from [Sales]
Hierarchy
C48
WITH MEMBER MEASURES.IIFDEMO AS IIF([Measures].[Unit Sales]>1000 , "Venda Alta", "Venda Baixa") SELECT --classifica venda como baixa ou alta {[Measures].[Unit Sales],MEASURES.IIFDEMO} ON 0, [Time].[Time].[Year].MEMBERS ON 1 FROM [Sales]
IIF
94
C49 with member [Measures].[Teste InStr] as 'InStr("Erivam","v")' select [Measures].[Teste InStr] on 0 from [Sales]
InStr
C50 SELECT --Retorna a interseção de dois conjuntos de entrada, mantendo as duplicatas. INTERSECT( {[Time].[Time].[Year].[1997].[Q1], [Time].[Time].[Year].&[1997]} , {[Time].[Time].[Year].&[1998],[Time].[Time].[Year].&[1997].[Q1]}) ON 0 FROM [Sales]
Intersect
C51 WITH MEMBER [Measures].[Teste] as 'ISEMPTY([Product].[Product Family].[Drink])' --Retorna se a expressão avaliada for o valor de célula vazio SELECT [Measures].[Teste] ON 0 FROM [Sales]
IsEmpty
C52 SELECT --Retorna um membro de uma tupla especificada {( [Time].[1997].&[Q1], [Measures].[Unit Sales] ).Item(0)} ON 0 ,{[Measures].[Store Cost]} ON 1 FROM [Sales]
Item
C53 SELECT --Retorna um membro de uma tupla especificada {( [Time].[1997].&[Q1], [Measures].[Unit Sales] ).Item(0)} ON 0 ,{[Measures].[Store Cost]} ON 1 FROM [Sales]
Item
C54 SELECT --Retorna um membro de uma tupla especificada {( [Time].[1997].[Q1], [Measures].[Unit Sales] ), ( [Time].[1997].&[Q2], [Measures].[Unit Sales])}.Item(0) ON 0 FROM [Sales]
Item
C55 SELECT --Retorna o membro que é um número especificado de posições antes de um membro especificado no nível do membro. {[Time].[1997].[Q2].Lag(1) } ON COLUMNS, {[measures].[Unit sales]} ON ROWS FROM [Sales]
Lag
C56
SELECT -- Último filho de um membro = member [Time].[Time].[Year].&[1997]. LASTCHILD on 0 FROM [Sales]
LastChild
95
C57 SELECT --Retorna um conjunto de membros até e inclusive um membro especificado. LastPeriods (3,[Time].[Time].[Quarter].[Q1] ) ON 0 FROM [Sales]
LastPeriods
C58 SELECT --Retorna o último filho do pai de um membro especificado. {[Time].[1997].[Q1].LastSibling } ON COLUMNS, [Unit Sales] ON ROWS FROM [Sales]
LastSibling
C59 SELECT --Retorna o membro que é um número especificado de posições que seguem um membro especificado junto ao nível do membro. {[Time].[1997].[Q1].[3].Lead(-1) } ON COLUMNS, [Measures].[Unit Sales] ON ROWS FROM [Sales]
Lead
C60 SELECT --Retorna o nível de um membro. [Time].[Time].[Year].[1997].Level.Members ON 0 FROM [Sales]
Level
C61
SELECT --Retorna um conjunto composto de todos os atributos {[Measures].[Unit Sales]} ON 0, {[Product].[Product].Levels(2).Members} ON 1 FROM [Sales]
Levels
C62
SELECT --Retorna um conjunto composto de todos os atributos {[Measures].[Unit Sales]} ON 0, {[Time].[Time].Levels("Year").Members} ON 1 FROM [Sales]
Levels
C63 WITH MEMBER [MEASURES].[Demo] AS 'LinRegIntercept(([Time].[Year].members),[Measures].[Unit Sales]) ' --Calcula a regressão linear de um conjunto e retorna o valor da interceptação de x na linha de regressão (y = ax + b). SELECT {[MEASURES].[Demo] } on 0 FROM [Sales]
LinRegIntercept
C64
WITH MEMBER [MEASURES].[Demo] AS 'LinRegPoint([Time].[Year].[1997],([Product].[Product].[Product Family].[Drink]),[Measures].[Unit Sales]) ' --Calcula a regressão linear de um conjunto e retorna o valor de y-intercept na linha de regressão (y = ax + b). SELECT {[MEASURES].[Demo] } on 0 FROM [Sales]
LinRegPoint
96
C65 WITH MEMBER [MEASURES].[Demo] AS 'LinRegR2(LastPeriods(10),[Measures].[Unit Sales]) ' --Calcula a regressão linear de um conjunto e retorna o coeficiente de determinação SELECT {[MEASURES].[Demo] } on 0 FROM [Sales]
LinRegR2
C66 WITH MEMBER [MEASURES].[Demo] AS 'LinRegSlope(LastPeriods(10),[Measures].[Unit Sales],[Measures].[Store Sales]) ' --Calcula a regressão linear de um conjunto e retorna o valor do declive na linha de regressão (y = ax + b). SELECT {[MEASURES].[Demo] } on 0 FROM [Sales]
LinRegSlope
C67 WITH MEMBER [MEASURES].[Demo] AS 'LinRegVariance(LastPeriods(10),[Measures].[Unit Sales]) ' --Calcula a regressão linear de um conjunto e retorna a variância associada à linha de regressão (y = ax + b). SELECT {[MEASURES].[Demo] } on 0 FROM [Sales]
LinRegVariance
C68
WITH MEMBER [Measures].[max categoria] AS MAX({[Product].[Product Category].members}) --Obter a maior venda entre as categorias SELECT [Measures].[max categoria] on 0 FROM [Sales]
Max
C69 WITH MEMBER [Measures].[Median] AS 'Median({[Product].[All Products].children})' --obter mediana das unidades vendidas SELECT {[Measures].[Median] } ON 0 FROM [Sales]
Median
C70 select --Retorna o conjunto de membros em uma dimensão, nível ou hierarquia. {[Measures].[Unit Sales]} ON COLUMNS, {[Time].[Time].Members} ON ROWS from [Sales]
Members
C71 select --Retorna o conjunto de membros em uma dimensão, nível ou hierarquia. [Time].[Time].[Year].Members ON 0 from [Sales]
Members
C72 select --Retorna o conjunto de membros em uma dimensão, nível ou hierarquia. Members('[Time].[Time].[Year].[1997]') ON 0 from [Sales]
Members
97
C73
WITH MEMBER [Measures].[min categoria] AS MIN({[Product].[Product Category].members}) --Obter a menor venda entre as categorias SELECT [Measures].[min categoria] on 0 FROM [Sales]
Min
C74 with member [Measures].[DemoMTD] as 'MTD()' --Retorna um conjunto de membros irmãos do mesmo nível como um determinado membro, começando com o primeiro irmão e terminando com um determinado membro, restringido pelo nível Ano na dimensão Tempo. select [Measures].[DemoMTD] on 0 from [Sales]
Mtd
C75 with member [Measures].[DemoName] as '[Time].Name' --Retorna o nome de uma dimensão, hierarquia, nível ou membro. select {[Measures].[DemoName]} ON COLUMNS from [Sales]
Name
C76 with member [Measures].[DemoName] as '[Time].[Time].Name' --Retorna o nome de uma dimensão, hierarquia, nível ou membro. select {[Measures].[DemoName]} ON COLUMNS from [Sales]
Name
C77 with member [Measures].[DemoName] as '[Time].[Year].[1997].Name' --Retorna o nome de uma dimensão, hierarquia, nível ou membro. select {[Measures].[DemoName]} ON COLUMNS from [Sales]
Name
C78 with member [Measures].[DemoName] as '[Time].[Time].[Year].Name' --Retorna o nome de uma dimensão, hierarquia, nível ou membro. select {[Measures].[DemoName]} ON COLUMNS from [Sales]
Name
C79 SELECT --Retorna o próximo membro no nível que contém um membro especificado. {[Time].[1997].[Q1].NextMember } ON COLUMNS, {[Measures].[Unit Sales]} ON ROWS FROM [Sales]
NextMember
C80 SELECT --Retorna o primeiro irmão entre os descendentes de um nível especificado, opcionalmente em um membro especificado. OpeningPeriod() ON 0 FROM [Sales]
OpeningPeriod
98
C81
SELECT -- ordenando de forma ascendente e respeitando a hierarquia (descendente = DESC) ORDER([Time].[Time].[Year].members, 1) on 0 FROM [Sales]
Order
C82 SELECT -- ordenando de forma ascendente e respeitando a hierarquia (descendente = DESC) ORDER([Time].[Time].[Year].members, "Erivam") on 0 FROM [Sales]
Order
C83 WITH MEMBER [Measures].[DayOrMonthLevel] AS '[Time].CurrentMember.Level.Ordinal ' SELECT --Retorna o valor ordinal com base em zero associado a um nível. { [Product].[Product].[Product Family].members } ON COLUMNS, { [Measures].[DayOrMonthLevel] } ON ROWS FROM [Sales]
Ordinal
C84 SELECT --Retorna um membro de um período anterior na mesma posição relativa como um membro especificado. { ParallelPeriod () } ON columns, [Measures].[Unit Sales] on rows FROM [Sales]
ParallelPeriod
C85
SELECT -- Pai de um membro = member [Time].[Time].[Year].[1997].[Q1].PARENT on 0 FROM [Sales]
Parent
C86
SELECT --Retorna um conjunto de membros irmão do mesmo nível de um determinado membro, começando com o primeiro irmão e terminando com um determinado membro { [Measures].[Unit Sales] } on COLUMNS, PERIODSTODATE() on ROWS FROM [Sales]
PeriodsToDate
C87
select --retorna membro anterior [Time].[Year].[1997].[Q3].Prevmember on 0 from [Sales]
PrevMember
99
C88
WITH MEMBER [Measures].[Caption] AS '[Time].[Year].[1997].Properties("Caption")' select --obtem propriedade do membro [Measures].[Caption] on 0 from [Sales]
Properties
C89 with member [Measures].[DemoQTD] as 'QTD()' select --Retorna um conjunto de membros irmãos do mesmo nível [Measures].[DemoQTD] on 0 from [Sales]
Qtd
C90 with member [Measures].[DateRank] as 'Rank(([Time].[Time].[1997], [Product].[Product].[Product Family].[Drink]), Descendants([Time].[Time], [Time].[Time].[Quarter]))' --Retorna a classificação com base em uma classificação de uma tupla especificada em um determinado conjunto. select {[Measures].[DateRank]} ON COLUMNS, {Descendants([Time].[Time], [Time].[Time].[Quarter])} ON ROWS from [Sales]
Rank
C91 WITH MEMBER [Measures].[Demo] AS 'SetToStr (Customers.Children)' --Retorna uma cadeia com formato da linguagem MDX que corresponde a um conjunto especificado. SELECT { [Measures].[Demo] } ON COLUMNS FROM [Sales]
SetToStr
C92 SELECT --Retorna os irmãos de um membro especificado, inclusive o próprio membro. [Time].[1997].[Q2].Siblings ON 0 FROM [Sales]
Siblings
C93 WITH MEMBER [Measures].[Stddev] AS 'Stddev({[Product].[All Products].children})' --obter o desvio padrão SELECT {[Measures].[Stddev]} ON 0 FROM [Sales]
Stddev
C94 WITH MEMBER [Measures].[StddevP] AS 'StdevP(([Product].[Product].[Product Family].[Drink].children))' --Retorna o desvio padrão de população de uma expressão numérica avaliada sobre um conjunto, usando a fórmula de população polarizada (dividindo por n). SELECT {[Measures].[StddevP]} ON 0 FROM [Sales]
StddevP
100
C95 WITH MEMBER [Measures].[Stdev] AS 'Stdev(([Product].[Product].[Product Family].[Drink].children))' --Retorna o desvio padrão de população de uma expressão numérica avaliada sobre um conjunto, usando a fórmula de população polarizada (dividindo por n). SELECT {[Measures].[Stdev]} ON 0 FROM [Sales]
Stdev
C96 WITH MEMBER [Measures].[StdevP] AS 'FORMAT(StdevP(([Product].[Product].[Product Family].[Drink].children)) , "#,###")' --Retorna o desvio padrão de população de uma expressão numérica avaliada sobre um conjunto, usando a fórmula de população polarizada (dividindo por n). SELECT {[Measures].[StdevP]} ON 0 FROM [Sales]
StdevP
C97
SELECT --Retorna um conjunto gerado, removendo membros calculados de um conjunto especificado. STRIPCALCULATEDMEMBERS({[Measures].[Unit Sales], [Measures].[Store Sales], [Measures].[Store Cost]}) ON COLUMNS FROM [Sales]
StripCalculatedMembers
C98
select {StrToMember("[Time].[1997].[Q2]")} ON COLUMNS, {[Measures].[Unit Sales]} ON ROWS from [Sales]
StrToMember
C99 SELECT StrToSet("[Product].[Product].[Product Family].[Drink]") ON COLUMNS, {[Measures].[Unit Sales] , [Measures].[Store Sales]} ON ROWS FROM [Sales]
StrToSet
C100 SELECT --Retorna a tupla especificada por uma cadeia de caracteres formatada em linguagem MDX. StrToTuple ("( [Product].[Product].[Product Family].[Drink] , [Time].[1997] ,[Measures].[Unit Sales])") ON COLUMNS FROM [Sales]
StrToTuple
C101 SELECT --Retorna um subconjunto de tuplas de um conjunto especificado. Subset(([Time].[Time].[Year].[1997].children), 1) ON 0, [Measures].[Unit Sales] on 1 FROM [Sales]
Subset
101
C102 WITH MEMBER [Measures].[soma alguns membros da categoria] AS SUM({[Time].[Year].[1997].&[Q1], [Time].[Year].[1997].&[Q3] }) --Obter a soma de alguns membros da categoria SELECT [Measures].[soma alguns membros da categoria] on 0 FROM [Sales]
Sum
C103 select --Retorna um subconjunto desde o final de um conjunto. Tail([Product].[Product].[Product Family].Members) ON COLUMNS from [Sales]
Tail
C104
SELECT --Alterna o estado de busca de membros. { [Measures].[Unit Sales]} on 0, ToggleDrillState ({ [Customers].[Customers].[Country].Members, [Customers].[Customers].&[USA].Children}, {[Customers].[Customers].[Mexico], [Customers].[Customers].&[Canada] } ) ON 1 FROM [Sales]
ToggleDrillState
C105 SELECT -- os X melhores TOPCOUNT({[Time].[Time].[Year].&[1997].CHILDREN}, 2) on 0 FROM [Sales]
TopCount
C106
SELECT -- os que concentram X% do todo TOPPERCENT({[Time].[Time].[Year].&[1997].CHILDREN},50,[Measures].[Unit Sales]) on 0 FROM [Sales]
TopPercent
C107
SELECT -- os que concentram X unidades do todo TOPSUM({[Time].[Time].[Year].&[1997].CHILDREN},130000,[Measures].[Unit Sales]) on 0 FROM [Sales]
TopSum
102
C108
WITH MEMBER [Measures].[x] AS 'TupleToStr ( ([Time].[Year].&[1997] , [Customers].[Country].&[USA] ) ) ' --Retorna uma cadeia com formato da linguagem MDX que corresponde a uma tupla especificada. SELECT {[Measures].[x]} ON COLUMNS FROM [Sales]
TupleToStr
C109
SELECT --Retorna um conjunto gerado pela união de dois conjuntos, retendo membros duplicados opcionalmente. Union ({[Time].[Time].[Year].[1997]} , {[Time].[Time].[Year].[1998]} ) ON 0, [Measures].[Unit Sales] ON 1 FROM [Sales]
Union
C110 WITH MEMBER [Measures].[Nome] as '[Product].Name' MEMBER [Measures].[NomeUnico] as '[Product].UniqueName' SELECT --Retorna o nome exclusivo de uma dimensão, hierarquia, nível ou membro especificado. {[Measures].[Nome], [Measures].[NomeUnico] } on 0 FROM [Sales]
UniqueName
C111 WITH MEMBER [Measures].[Nome] as '[Product].[Product Name].Name' MEMBER [Measures].[NomeUnico] as '[Product].[Product Name].UniqueName' SELECT --Retorna o nome exclusivo de uma dimensão, hierarquia, nível ou membro especificado. {[Measures].[Nome], [Measures].[NomeUnico] } on 0 FROM [Sales]
UniqueName
103
C112
WITH MEMBER [Measures].[Nome] as '[Product].[Product Family].[Drink].Name' MEMBER [Measures].[NomeUnico] as '[Product].[Product Family].[Drink].UniqueName' SELECT --Retorna o nome exclusivo de uma dimensão, hierarquia, nível ou membro especificado. {[Measures].[Nome], [Measures].[NomeUnico] } on 0 FROM [Sales]
UniqueName
C113 WITH MEMBER [Measures].[Nome] as '[Store Type].[Store Type].Name' MEMBER [Measures].[NomeUnico] as '[Store Type].[Store Type].UniqueName' SELECT --Retorna o nome exclusivo de uma dimensão, hierarquia, nível ou membro especificado. {[Measures].[Nome], [Measures].[NomeUnico] } on 0 FROM [Sales]
UniqueName
C114 SELECT --Remove qualquer classificação forçada de um conjunto especificado. {DESCENDANTS([Time].[1997].[Q2],1)} ON COLUMNS, UNORDER([Product].[Product].[Product Family].Members) ON ROWS FROM [Sales]
Unorder
C115 with member [Measures].[valor_ValidMeasure] as 'Format(ValidMeasure([Measures].[Store Sales]),"#,###.##")' --Retorna o valor de uma medida em um cubo, forçando dimensões inaplicáveis para o nível Todos (ou o membro padrão, se não agregável) durante o retorno de resultados para uma tupla especificada. select {[Measures].[valor_ValidMeasure]} ON COLUMNS, {[Product].[Product].[Product Family].members} ON ROWS from [Sales]
ValidMeasure
C116 with member [Time].[1997].[NumericValue] as '[Time].[1997].Value' --Retorna o valor do membro atual da dimensão Medidas que faz interseções com o membro atual das hierarquias do atributo no contexto da consulta. select {[Time].[1997].[NumericValue]} ON COLUMNS from [Sales]
Value
104
C117 WITH MEMBER [Measures].[Var] AS 'Var({[Product].[Product].[Product Family].[Drink].children})' --Retorna a variância de exemplo de uma expressão numérica avaliada sobre um conjunto, usando a fórmula de população não-polarizada (dividindo por n-1). SELECT {[Measures].[Var]} ON 0 FROM [Sales]
Var
C118 WITH MEMBER [Measures].[Variance] AS 'Variance({[Product].[Product].[Product Family].[Drink].children})' --Retorna a variância SELECT {[Measures].[Variance]} ON 0 FROM [Sales]
Variance
C119 WITH MEMBER [Measures].[VarianceP] AS 'VarianceP({[Product].[Product].[Product Family].[Drink].children})' --Retorna a variância SELECT {[Measures].[VarianceP]} ON 0 FROM [Sales]
VarianceP
C120 WITH MEMBER [Measures].[VarP] AS 'VarP({[Product].[Product].[Product Family].members})' --Retorna a variância de exemplo de uma expressão numérica avaliada sobre um conjunto, usando a fórmula de população não-polarizada (dividindo por n-1). SELECT {[Measures].[VarP]} ON 0 FROM [Sales]
VarP
C121
SELECT --Retorna um conjunto gerado com a totalização dinâmica de membros filho em um conjunto especificado, utilizando, opcionalmente, um padrão para o nome do membro pai no conjunto de resultados. VisualTotals({[Time].[1997].[Q1].&[1] ,[Time].[Time].[Month].&[1]}) ON 0, [Measures].[Unit sales] on 1 FROM [Sales]
VisualTotals
C122 Select [Measures].[Unit Sales] ON COLUMNS, --Retorna um conjunto de membros irmãos do mesmo nível como um determinado membro, começando com o primeiro irmão e terminando com um determinado membro, restringido pelo nível Semana na dimensão Tempo. {WTD()} on rows from [Sales]
Wtd
105
APÊNDICE H – FUNÇÕES SOBRECARREGADAS
Neste apêndice tem-se um quadro com as funções sobrecarregadas do
Analysis Services e do Mondrian.
Analysis Services Mondrian
1. AllMembers 1. AllMembers
2. Ancestor 2. Ancestor
3. CoalesceEmpty 3. ClosingPeriod
4. Count 4. Count
5. Descendants 5. CurrentMember
6. Dimension 6. DefaultMember
7. Dimensions 7. Dimension
8. Generate 8. Dimensions
9. Hierarchy 9. Generate
10. Item 10. Hierarchy
11. Levels 11. IsEmpty
12. Members 12. Item
13. Name 13. Levels
14. Order 14. Members
15. UniqueName 15. Name
16. Order
17. UniqueName