Thursday, December 17, 2015

SSAS Single Role - Multiple Dimensions Issue...

In my previous post, I explained how to provide access using multiple roles for different dimensions.
Also I faced issues while providing access for multiple dimensions using a single role.

Let assume a scenario that we only need to provide the access for a Sales Manager, only for his Current Region. But Region of the Sales Manager may be changed and he should be able to see the relevant data for the Region for the period he assigned for that Region.

As I explained in my previous post, we need to maintain a mapping table for this requirement as well. Lets assume the name of the mapping table is SECURITY_MANAGER_REGION and the columns will be SalesManagerId, RegionId and MonthId. In this scenario I assumed sales manager is assigned for a particular region, at least for a period of Month.

Then we need to have the SECURITY_MANAGER_REGION table data in a fact table and can grant the access for the Region and Month dimensions based on it with in the same role.

But the issue is since those are two different dimension, security is applied separately and it is causing the issue.

To overcome that what I have done was, add a composite key using RegionId and MonthId  values to the SECURITY_MANAGER_REGION table.
Based on that table created a new dimension as DIM_SECURITY_MANAGER_REGION which uses the Key as the composite keys of RegionId and MonthId.

Then the Security is applied for the DIM_SECURITY_MANAGER_REGION dimension and the same dimension is linked with the measure groups using the RegionId and MonthId values.

That is it!

Friday, November 6, 2015

Multiple Roles - Different Dimensions in SSAS Security is not impossible...

We had a requirement to implement dynamic security in SSAS with multiple roles for different dimensions.
But due to the Additive design of SSAS security, it is causing issues and people think that is impossible.
But I found the below useful link, which mentioned some of the alternative approaches.
http://blogs.msdn.com/b/psssql/archive/2014/07/30/the-additive-design-of-ssas-role-security.aspx

Actually to have multiple roles for different dimensions, you need to consider below scenarios

  1. If you allow access in one role, you need to restrict that in the other roles.
  2. Need to consider the scenario that the user is not belongs to any of the roles and restrict access in that scenario as well.
  3. Also make sure that you put the tick for the Enable Visual Total check box in the security applied attribute.
Instead of the custom assembly approach mentioned in the above link, I was able to get done the same using a reference table and have that as a Non-Additive fact in the cube.

As an example let say we have two dimension as Customer and Region and we need to restrict the access for those based on the Sales Person. To provide the access for Customer data, there is a role as Role_Customer and to provide the access for Region data, there is a role as Role_Region.

To achieve that there are two mapping tables are maintained as SECURITY_REGION (Columns as SalesPersonId, RegionId) and SECURITY_CUSTOMER (Columns as SalesPersonId, RegionId) to keep the relevant mappings. Two measure groups are created based on those mapping tables as SECURITY REGION and SECURITY CUSTOMER to use the mapping tables in the cube.

In the SECURITY_REGION role, security is provided for the Region dimension using the below expression. You need provide expression for the Allowed member set of the RegionId attribute of the Region dimension, under the Dimension Data.

Exists
(
{[DIMREGION].[REGIONID].[REGIONID].Members},
STRTOSET("[LOGIN].[PERSON NAME].&["+username()+"]"),
"SECURITY REGION ")

LOGIN Dimension maintains the log in details of the users and it uses to capture the relevant logged user.

In the same way, security can be provided for the Customer dimension using SECURITY_CUSTOMER role, by using the below mdx expression for the CustomerId attribute in the Customer dimension.

Exists
(
{[DIMCUSTOMER].[CUSTOMERID].[CUSTOMERID].Members},
STRTOSET("[LOGIN].[PERSON NAME].&["+username()+"]"),
"SECURITY CUSTOMER ")

But if you only follow above steps, security will not be applied due to the Additive design of SSAS Security.
To avoid it we need to follow the second step mentioned in the top of the post and it can be done as below.

In the SECURITY_REGION role, we need make sure if the user is in the SECURITY_CUSTOMER role, then for the CustomerId attribute of the Customer dimension, we need to restrict all the members since the 
security will be applied from the SECURITY_CUSTOMER role. Otherwise we need to allow all the members.

We can achieve it by applying the below mdx expression for allowed member set of the CustomerID attribute of the Customer dimension in the SECURITY_REGION role.

IIF(Count(NonEmpty
(
{[DIMCUSTOMER].[CUSTOMERID].[CUSTOMERID].Members}*
STRTOSET("[LOGIN].[PERSON NAME].&["+username()+"]"),

[Measures].
[SECURITY CUSTOMER Count]))>0 OR 
(Count(NonEmpty
(
{[DIMCUSTOMER].[CUSTOMERID].[CUSTOMERID].Members}*
STRTOSET("[LOGIN].[PERSON NAME].&["+username()+"]"),

[Measures].
[SECURITY CUSTOMER Count]))=0 AND 
COUNT(NonEmpty
(
{[DIMREGION].[REGIONID].[REGIONID].Members}*

STRTOSET("[LOGIN].[PERSON NAME].&["+username()+"]"),
[Measures].[SECURITY REGION Count]))=0) ,
{},{[DIMCUSTOMER].[CUSTOMERID].[CUSTOMERID].Members})


We have to do the same thing for the RegionId attribute in the SECURITY_CUSTOMER  role.

Also make sure that you put the tick for the Enable Visual Total check box in all the security applied attributes.

These steps will allow you to provide security based on Multiple Roles for Different Dimensions.

Thursday, October 15, 2015

Errors in the OLAP storage engine: A duplicate attribute key has been found when processing:

While processing a dimension, processing got failed and shown the below warning as well.
Errors in the OLAP storage engine: A duplicate attribute key has been found when processing:..

But when I checked the values of the mentioned attribute, there were no duplicate values. But the relevant column data type is INT and it has a value as NULL.
When I checked the dimension attribute key column properties, NullProcessing property is set to Automatic.
Actually this is causing the above error message since during the processing, NULL values are converted to 0 and we already have an attribute value as 0.
Same issue can happen for the string data types having blank value as well.

To fix this we can replace NULL values with the relevant value in the Data Source View of the Cube or replace it in the Data Warehouse using the ETL. Best way to do is to change it in the Data Warehouse.

Below link contains more details about this issue as well.


Thursday, October 8, 2015

Error message when trying to open SQL Server Configuration Manager in SQL Server: "Cannot connect to WMI provider. You do not have permission or the server is unreachable"

We had an issue that SQL Server Analysis Server is not getting started and cannot connect to the SQL Server Configuration Manager as well. While trying to connect to the SQL Server Configuration Manager, got the below error message.

Cannot connect to WMI provider. You do not have permission or the server is unreachable. Note that you can only manage SQL Server 2005 and later servers with SQL Server Configuration Manager.

According to the below Microsoft support link, it says that the WMI Provider file is removed when the SQL Server is uninstalled.

https://support.microsoft.com/en-us/kb/956013

But in my case that is not the reason, since we did not do any uninstall. Possible reason could be that file is corrupted.

Before following the steps mentioned in the link, you can just try the below steps.


  • Stop the Analysis Service service
  • Restart the Windows Management Instrumentation service
  • Then try to restart the SQL Server Analysis Service service.
  • Check whether the SQL Server Analysis Service service is getting started, if not follow the steps mentioned in the link as below.


  • open a command prompt, type the following command, and then press ENTER:
  • mofcomp "%programfiles(x86)%\Microsoft SQL Server\number\Shared\sqlmgmproviderxpsp2up.mof"
  • Note For this command to succeed, the Sqlmgmproviderxpsp2up.mof file must be present in the %programfiles(x86)%\Microsoft SQL Server\number\Shared folder.

  • The value of number depends on the version of SQL Server:nnn
    Microsoft SQL Server 2012 - 110
    Microsoft SQL Server 2008 R2 - 100
    Microsoft SQL Server 2008 - 100
    Microsoft SQL Server 2005 - 90
  • Then restart the Windows Management Instrumentation service.
  • After that restart the SQL Server Analysis Service service as well.


This should fix both the issues mentioned above.

Monday, September 28, 2015

How to prevent first time cube access performance issue, after a cube refresh with Dynamic Security...

Recently we faced an issue that, after a cube refresh there is a performance issue while accessing the cube. This happens since the dynamic security was implemented.
This performance issue can be prevented by building cache for each user.

SSIS package was implemented to build the cache. In the package the approach used was to execute the create cache mdx command using each user id.
You can connect to the SSAS cube with different users by using the EffectiveUserName property in the Connection String.

The structure of the package is as shown below



Steps:

  • Create four variables as shown below. 





  • OLAP_ConnString is the value used as the connection string for SSAS cube. It includes the user name by using the EffectiveUserName property.
  • UserNames variable is used to get the list of users. 
  • Each user is assigned to UserName variable in the Foreach Loop Container.




  • Execute SQL Task us used with in the Foreach Loop Container use to create the cache using the MDX command. Since Effective User Name property is set using the UserName variable, the MDX command is executed for the particular user. That means the cache was created for that user.


After a cube refresh, we need to execute this package and it will prevent the first time access performance issue.





Tuesday, June 9, 2015

Problems when trying to get changed records from...

The SSIS Package was configured to get only the net changes by applying the CDC processing mode as Net in the CDC Source.
But when the SSIS package was executed, got the below error message.
"Problems when trying to get changed records from dbo_testcdc. Reason - Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding..".

The issue was fixed by using the below steps.


  • Right click on the CDC Source and select Properties.
  • In the properties window find the Command Timeout and change it to 0. Default value of this property is 30.
  • Save the package and execute it. It should run without any issue.

Saturday, April 11, 2015

CDC Failed when changing the database or the CDC State table in SSIS Package...

Recently we faced that the SSIS packages got failed which use CDC, due to a validation issue when the data source is pointing to a different database or the CDC State table is pointing to a different one.

The solution is to set the Delay Validation property to True.
But I found that sometimes this is not enough in the package level and need to set it in the Data Flow and the set ValidateExternalMetaData to False in the CDC Source as well.

Hope this is helpful for you as well.

Friday, February 6, 2015

Rank SSAS Cube data based on a filtered data set using MDX...

I explained how we can use MDX ranking in the below two posts.
MDX Rank and Advanced MDX Ranking.

But the queries given in those two posts will not work if you are filtering data using a dimension which is used for ranking and data is filtered using a sub cube. In such a case it will rank the data using the all the data set and filter it after that. If you filter it in the Where statement, Rank will work fine. But the issue is in this scenario you cannot use it, since the same dimension attribute is already used in the query.

To avoid this, we need to only use the filtered dimension members in the ranking calculation as well.
The sample query is as below. In that, ranking needs to be done for the selected stores and the used parameter is paramStores.

WITH
MEMBER [Measures].[RankSales] AS
RANK(([Store—Region_Store].CurrentMember,[Store—Region].CurrentMember,[Item—Department].CurrentMember),
ORDER(({STRTOSET(@paramStores)*[Store—Region].CurrentMember*[Item—Department].CurrentMember}),
[Measures].[Sales], BDESC))

SELECT {[Measures].[RankSales]} ON COLUMNS,
{STRTOSET(@paramStores)*[Item—Department].[Department].MEMBERS} ON ROWS
FROM  [Sales]

The output will be ranked only based on the available values in the paramStores parameter.