
Wat niet iedereen weet is dat je in Analysis Services de default member van iedere attribuut hiërarchie in kunt stellen. Als je dat niet doet en je refereert in een MDX expressie niet aan een hiërarchie, wordt voor die hiërarchie standaard de (All) member gebruikt (verondersteld dat de hiërarchie ‘aggregatable’ is). Middels de DefaultMember property van een attribuut hiërarchie, kun je dit standaard gedrag veranderen. De property kan ‘hard’ ingesteld worden op iedere member binnen de hiërarchie, maar middels een MDX statement kun je dit ook dynamisch doen.
Je zou dit in de AdventureWorks sample database toe kunnen passen door de default member in de Sales Territory dimensie in te stellen op het land waarvoor de huidig ingelogde AdventureWorks medewerker verantwoordelijk is. Die verantwoordelijkheid ligt vast in de relatie tussen de Employee en de Sales Territory dimensie. Een extra measure group waarin die relatie middels een eenvoudige count measure is vastgelegd, geeft een soort matrix waarin een 1 staat op de kruising van medewerker en één Sales Territory:
De AdventureWorks database bevat al een LoginID attribuut in de Employee dimensie die default niet browsable is. Als je die browsable maakt (AttributeHierarchyEnabled op True zetten) en je zorgt dat je ingelogd bent met een login naam die overeen komt met één van de LoginID attribuut waarden, geeft het volgende MDX statement voor die login naam de member in de Sales Territory dimensie terug waar een waarde staat op de kruising met die dimensie en de Employee dimensie:
TAIL(EXISTS([Sales Territory].[Sales Territory Region].Members, STRTOMEMBER("[Employee].[Login ID].[" + UserName + "]"), "Employee"), 1).ITEM(0)
Je moet hier de TAIL functie gebruiken omdat de EXISTS functie ook de members terug geeft op hiërarchisch hogere niveaus, zoals Europa. Merk verder op dat je de ITEM(0) functie nodig hebt; de TAIL functie geeft een set terug, in dit geval met slechts één member omdat als laatste argument een 1 wordt opgegeven. Maar het blijft een set, terwijl de DefaultMember property een member verwacht. ITEM(0) geeft de enige member in de set als member terug.
Zou je dit MDX statement in de DefaultMember property van de Sales Territory dimensie zetten, zul je merken dat het niet werkt. De reden is eigenlijk heel eenvoudig: in het MDX statement wordt verondersteld dat er een context is die bepaald wordt door de measure group waarin de dimensie gebruikt wordt. Er wordt ook verwezen naar een andere dimensie (Employee). Dat kan pas binnen een kubus, niet in een dimensie. Kortom, je kunt de DefaultMember property van een attribuut hiërarchie niet op deze manier met dit MDX statement veranderen. Dat kan pas wanneer je de dimensie in een kubus gebruikt. Bijvoorbeeld door in die kubus het volgende statement op te nemen in het CALCULATE script:
Alter Cube
    CurrentCube
        Update Dimension [Sales Territory],
            Default_Member = TAIL(EXISTS([Sales Territory].[Sales Territory Region].Members,
                                  STRTOMEMBER("[Employee].[Login ID].[" + UserName + "]"), "Employee"), 1).ITEM(0);
Als je hierna de Sales Territory dimensie niet gebruikt in een query, zie je alleen datgene wat hoort bij de Sales Territory van de huidig ingelogde gebruiker. Log je bijv. in met de login ID die hoort bij Jae B. Pak die verantwoordelijk is voor de UK, zie je als totaal Internet Sales Amount 3,39 M.
Dat is het bedrag wat hoort bij de United Kingdom, wat je ziet zodra je de Sales Territory dimensie wel in de query opneemt:
Merk op dat de hier beschreven methode geen security mechanisme is. Sterker nog, dit is eigenlijk makkelijker te realiseren wanneer je dit via security regelt. Ik hoop alleen dat het je inspireert tot het maken van nog mooiere, dynamische, gepersonaliseerde Analysis Services oplossingen!