SSAS - Is it possible to add an attribute to an existing dimension w/o redeploying the entire cube - ssas

I have a dimension Entity with just Key and Value attributes. We need to add a new attribute, IsSpecial with a default member of [False].
When I try to run the xmla, I get the following error:
Errors in the metadata manager. The
cube with the ID of 'X', Name
of 'Y' was invalidated by
operations in the transaction.
Here's a fragment of the XMLA used to alter the dimension
<Dimension>
<ID>Dim Entity</ID>
<Name>Entity</Name>
<UnknownMemberName>Unknown</UnknownMemberName>
<Attributes>
<Attribute>
<ID>Dim Entity</ID>
<Name>Entity</Name>
<Usage>Key</Usage>
<EstimatedCount>119</EstimatedCount>
<KeyColumns>
<KeyColumn>
<DataType>Integer</DataType>
<Source xsi:type="ColumnBinding">
<TableID>shared_DimEntity</TableID>
<ColumnID>EntityKey</ColumnID>
</Source>
</KeyColumn>
</KeyColumns>
<NameColumn>
<DataType>WChar</DataType>
<DataSize>32</DataSize>
<Source xsi:type="ColumnBinding">
<TableID>shared_DimEntity</TableID>
<ColumnID>EntityValue</ColumnID>
</Source>
</NameColumn>
<AttributeRelationships>
<AttributeRelationship>
<AttributeID>IsSpecial</AttributeID>
<Name>IsSpecial</Name>
</AttributeRelationship>
</AttributeRelationships>
</Attribute>
<Attribute>
<ID>IsSpecial</ID>
<Name>IsSpecial</Name>
<KeyColumns>
<KeyColumn>
<DataType>Boolean</DataType>
<Source xsi:type="ColumnBinding">
<TableID>shared_DimEntity</TableID>
<ColumnID>IsShadowTracking</ColumnID>
</Source>
</KeyColumn>
</KeyColumns>
<NameColumn>
<DataType>WChar</DataType>
<Source xsi:type="ColumnBinding">
<TableID>shared_DimEntity</TableID>
<ColumnID>IsShadowTracking</ColumnID>
</Source>
</NameColumn>
<DefaultMember>[Entity].[IsSpecial].[False]</DefaultMember>
</Attribute>
</Attributes>
<Hierarchies>
<Hierarchy>
<ID>Hierarchy</ID>
<Name>Hierarchy</Name>
<Levels>
<Level>
<ID>IsSpecial</ID>
<Name>IsSpecial</Name>
<SourceAttributeID>IsSpecial</SourceAttributeID>
</Level>
</Levels>
</Hierarchy>
</Hierarchies>
</Dimension>
Any suggestions?

I doubt there is a way of doing this.
When changing dimension model you also modify cubes which use that dimension. Without redeploying the whole cube, metadata manager doesn't know about changes in cube.
The same situation occurs when changing dimensions in BIDS on-line - appropriate cubes are affected so they need to be deployed again.

"Recall that ROLAP partition-mode storage means that source data is not
copied to the SSAS destination. Another characteristic of ROLAP partition storage is that
aggregations are written back to relational tables in the source schema."
"To set a dimension as a ROLAP dimension, open the Dimension editor in BIDS, and in the Properties window for that dimension change the StorageMode property from the default MOLAP to ROLAP"
"though this requires Enterprise Ed of SSAS"

Related

Name of the user who has processed the cube

There is a code piece in which I have to get the username of the user who has processed the cube or has made any changes in the cube structure.
I have searched in the SSAS DMV's, but didn't find what I needed; I only found the last processed time, but not the name of the user.
Any suggestions?
You can track this using an Extended Event. Add the ProgressReportBegin and ProgressReportEnd events which are for processing. These events include the NTUserName and StartTime fields which you can use to find who processed the cube and when. The Extended Event will need to be running when the cube is processed to capture this. The following is an example XMLA command which can be run when connected to your SSAS database in SSMS to create an Extended Event that tracks cube processing and outputs the results to a file. Of course many of these options are just defaults and you may want to make adjustments as necessary.
https://learn.microsoft.com/en-us/sql/analysis-services/instances/monitor-analysis-services-with-sql-server-extended-events?view=sql-server-2017
<Create xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<ObjectDefinition>
<Trace>
<ID>XE_Cube_Process</ID>
<Name>XE_Cube_Process</Name>
<XEvent xmlns="http://schemas.microsoft.com/analysisservices/2011/engine/300/300">
<event_session name="XE_Cube_Process" dispatchLatency="0" maxEventSize="0" maxMemory="4" memoryPartition="none" eventRetentionMode="AllowSingleEventLoss" trackCausality="true" xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<event package="AS" name="ProgressReportEnd" />
<event package="AS" name="ProgressReportBegin" />
<target package="package0" name="event_file">
<parameter name="filename" value="C:\Test\XE_Cube_Process.xel" />
<parameter name="max_file_size" value="4096" />
<parameter name="max_rollover_files" value="10" />
<parameter name="increment" value="1024" />
</target>
</event_session>
</XEvent>
</Trace>
</ObjectDefinition>
</Create>

Alter cube dimension by using XMLA

By using XMLA how to access WriteEnabled dimension property and modify it?
Here is a sample I'm using for that
<Alter ObjectExpansion="ExpandFull" xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<Object>
<DatabaseID>DB</DatabaseID>
<DimensionID>My dimension</DimensionID>
</Object>
<ObjectDefinition>
<Dimension xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ddl2="http://schemas.microsoft.com/analysisservices/2003/engine/2"
xmlns:ddl2_2="http://schemas.microsoft.com/analysisservices/2003/engine/2/2" xmlns:ddl100_100="http://schemas.microsoft.com/analysisservices/2008/engine/100/100">
<WriteEnabled>false</WriteEnabled>
<ID>My dimension</ID>
<Name>Dimension name</Name>
<Attributes>
<Attribute>
<Name>Attribute name/Name>
</Attribute>
</Attributes>
</Dimension>
</ObjectDefinition>
</Alter>
Running this script I'm getting following error: Errors in the metadata manager. The 'My dimension' dimension has either zero or multiple key attributes.
What is missing in a script above?
Seems the key columns node and Name columns nodes for your attribute have missing:
Here is an example for a dim attributes node, hope it helps:
You can create a cube manually, and then check the alter script by right click the cube name for a reference also.

Document id reference desn't work for impex

I have a problem with impex which contains document id reference.
From docs:
"Especially for importing partOf item values it is necessary to reference these items by means other than the usual unique column technique because partOf items often do not provide a unique key but only hold their enclosing parent as foreign key."
Items from *items.xml (only the most important parts)
<itemtype code="A" autocreate="true" generate="true" abstract="true"/>
<itemtype code="B" autocreate="true" generate="true" extends="A">
<deployment table="btable" typecode="20115" />
<attributes>
<attribute qualifier="code" type="java.lang.Integer" autocreate="true" generate="true">
<persistence type="property"/>
<modifiers optional="false"/>
</attribute>
</attributes>
</itemtype>
<itemtype code="C" autocreate="true" generate="true">
<deployment table="ctable" typecode="20117" />
<attributes>
<attribute qualifier="code" type="java.lang.String" autocreate="true" generate="true">
<persistence type="property"/>
<modifiers optional="false" unique="true"/>
</attribute>
<attribute qualifier="test" type="A" autocreate="true" generate="true">
<persistence type="property"/>
<modifiers optional="false" partof="true"/>
</attribute>
</attributes>
</itemtype>
Impex code:
INSERT B;code;&docIdRef
;1;docId
INSERT_UPDATE C;code[unique=true];test(&docIdRef)
;uniqueCode;docId
Error message:
cannot create C with values ItemAttributeMap[ registry: null, type: <null>, (...) due to [de.hybris.platform.servicelayer.interceptor.impl.MandatoryAttributesValidator#3b777877]:missing values for [test] in model C
When I removed 'partof' modifier from 'test' attribute (C class) everything worked fine.
I wonder how impex should looks like if i want to keep 'partof' modifier.
When you use partOf you must reference the partOf using the owner.
So it does :
INSERT B;owner(C.code);&docIdRef
;uniqueCode;docId
INSERT_UPDATE C;code[unique=true];test(&docIdRef)
;uniqueCode;docId
You don't need to assign B an identifier, you just need to reference the owner.
If you know for sure that your data is correct you can use [forceWrite=true] modifier or legacy mode to skip service layer validation.
You should also make sure that this configuration is what you really need. Setting either optional to true or partOf to false or providing default value should fix the issue as well.
Since you have mentioned partof="true" you can not assign a reference of type A. You can only create a new entity.
Check the OOTB AbstractOrder2AbstractOrderEntry relationship, they have mentioned partof="true" for AbstractOrderEntry means you can't reference any other AbstractOrderEntry to Order. You can always create new entry.
Have a look at HMC site as well
You can see here there is no + Add Entry button available here. The reciprocal can be possible.

MDX Attribute Value Key

I've faced such a problem:
I have a dimension [Project_sales] with one hierarchy [Default] in my cube [Sales_planning_RP].
I've created a custom property for this dimension and named it "Object".
When I created it I was asked for:
1)Property Key
2)Property value
Now I Have Source-table for this dimension with 2 additional fields:
1) [Object_code] ex:('O01') <-This is what I need (see question below)
2) [Object_name] ex: ('Object # 3213, editable') <-This is What I get
But I see only one property in OLAP:
[Project_sales].[Default].CurrentMember.Properties("Object")
Which gives me just Object_name.
So my question is how can I get the key of my property "Object" with MDX?
My dimension properties:
http://i.stack.imgur.com/N2Aej.png
My dimension has the following "parent_child" hierarchy:
Project->Object->Element_of_area
Every element of this hierarchy has as attribute "Object", which can be called in such a way:
[Project_sales].[Default].CurrentMember.Properties("Object")
In the properties window (in my picture) of the attribute "Object" there are 2 properties:
1)keyColumns
2)NameColumns
I repeat: "Object" here is not a member of dimension, it's an attribute!
And it has its own key and name.
I can get its name, but can't understand how to get its key, which is also loaded into cube.
Look at my member_properties list:
image_2
And here is a part of XMLA-code of my dimension to makes things clear:
<Attribute>
<Annotations>
<Annotation>
<Name>TypeOfInformation</Name>
<Value>1</Value>
</Annotation>
<Annotation>
<Name>TypeOfNameInformation</Name>
<Value>1</Value>
</Annotation>
<Annotation>
<Name>P4SSAMOVersion</Name>
<Value>2</Value>
</Annotation>
</Annotations>
<ID>Object</ID>
<Name>Object</Name>
<KeyColumns>
<KeyColumn>
<DataType>WChar</DataType>
<DataSize>40</DataSize>
<Source xsi:type="ColumnBinding">
<TableID>_x0036_Project_sales</TableID>
<ColumnID>Object_code</ColumnID>
</Source>
</KeyColumn>
</KeyColumns>
<NameColumn>
<DataType>WChar</DataType>
<DataSize>255</DataSize>
<Source xsi:type="ColumnBinding">
<TableID>_x0036_Project_sales</TableID>
<ColumnID>Object_name</ColumnID>
</Source>
</NameColumn>
<OrderBy>Key</OrderBy>
<MembersWithData>NonLeafDataHidden</MembersWithData>
<AttributeHierarchyVisible>false</AttributeHierarchyVisible>
</Attribute>
Ok, now it's clear!
There are 3 properties of an Attribute that may contain data:
1)Key
2)Name
3)Value
If Name is not empty and Key is not empty, you get Name when call .Properties() function.
If Name is empty and Key is not empty, you get Key.
Here is the source: https://www.mssqltips.com/sqlservertip/3271/sql-server-analysis-server-ssas-keycolumn-vs-namecolumn-vs-valuecolumn/

Check if SSAS Cube is available i.e. processed

I am looking for a method to check if a cube is accessable i.e. it is processed and not broken.
Example: I got a working cube and i full process a shared dimension so that the cube gets broken.
Is there any mdx or xmla method of finding out what cubes are accessable / processed?
There is an XMLA command DISCOVER_XML_METADATA that can return the state of the database (processes/unprocessed) among other properties. I don't have the best handle on XMLA, so I don't know how to get just the part you need, but this query will return results in the form of XML, and you can parse it from there.
<Discover xmlns="urn:schemas-microsoft-com:xml-analysis">
<RequestType>DISCOVER_XML_METADATA</RequestType>
<Restrictions>
<RestrictionList>
<DatabaseID>AdventureWorks2012MD</DatabaseID>
</RestrictionList>
</Restrictions>
<Properties>
<PropertyList>
</PropertyList>
</Properties>
</Discover>
This requests gets the properties from the objects related to the SSAS database called AdventureWorks2012M. In the results you will see the following:
<Database>
<Name>AdventureWorks2012MD</Name>
<ID>AdventureWorks2012MD</ID>
<CreatedTimestamp>2013-08-01T01:41:10.926667</CreatedTimestamp>
<LastSchemaUpdate>2013-08-01T01:45:05.91</LastSchemaUpdate>
<Description />
<LastProcessed>2013-08-01T01:46:39.713333</LastProcessed>
<State>Processed</State>
<LastUpdate>2014-01-07T19:41:45.146667</LastUpdate>
<AggregationPrefix />
<Language>1033</Language>
<Collation>Latin1_General_CI_AS</Collation>
<Visible>true</Visible>
...
You care about <State>Processed</State>for that database. You can also get the state for each of the dimensions and measure groups as well by adding MeasureGroupID or DimensionID to the restrictions list.