<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" >

<channel><title><![CDATA[Microsoft Data & AI - SSAS]]></title><link><![CDATA[https://www.delorabradish.com/ssas]]></link><description><![CDATA[SSAS]]></description><pubDate>Tue, 08 Apr 2025 23:27:42 -0700</pubDate><generator>Weebly</generator><item><title><![CDATA[SSAS 2016 Monitoring and Performance Tuning with Extended Events webinar]]></title><link><![CDATA[https://www.delorabradish.com/ssas/ssas-2016-monitoring-and-performance-tuning-with-extended-events-webinar]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/ssas-2016-monitoring-and-performance-tuning-with-extended-events-webinar#comments]]></comments><pubDate>Tue, 07 Mar 2017 17:09:57 GMT</pubDate><category><![CDATA[Extended Events]]></category><category><![CDATA[SSAS]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/ssas-2016-monitoring-and-performance-tuning-with-extended-events-webinar</guid><description><![CDATA[At the bottom of this blog post you will find the ZIP file referenced in today's webinar&nbsp;from Pragmatic Works.Webinar Talking Points:&nbsp; &nbsp; &nbsp;1. &nbsp;SSAS Performance Optimization 10K Foot View&nbsp; &nbsp; &nbsp;2. &nbsp;Profiler vs Extended Events&nbsp; &nbsp; &nbsp;3. &nbsp;SQL Server Instance QueryLog Properties&nbsp; &nbsp; &nbsp;4. &nbsp;SQL Server 2016 Profiler &amp; Extended Events Demos&nbsp; &nbsp; &nbsp;5. &nbsp;Interpreting Extended Events Data&nbsp; &nbsp; &nbsp;6.  [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><font color="#2a2a2a">At the bottom of this blog post you will find the ZIP file referenced in </font><u><a href="http://pragmaticworks.com/Training/Details/SSAS-2016-Monitoring-and-Performance-Tuning-with-Extended-Events" target="_blank" style="color: rgb(224, 145, 92);">today's webinar</a></u><font color="#2a2a2a">&nbsp;from Pragmatic Works.</font><br /><br /><font color="#c2743b"><strong>Webinar Talking Points:</strong></font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;1. &nbsp;SSAS Performance Optimization 10K Foot View</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;2. &nbsp;Profiler vs Extended Events</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;3. &nbsp;SQL Server Instance QueryLog Properties</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;4. &nbsp;SQL Server 2016 Profiler &amp; Extended Events Demos</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;5. &nbsp;Interpreting Extended Events Data</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;6. &nbsp;Extended Events Integration with SSIS Demo</font><br /><br /><font color="#c2743b"><strong>ZIP File Contents:</strong></font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;1. &nbsp;Slide deck in PDF format with and without notes</font><br /><font color="#2a2a2a">&nbsp;&nbsp; &nbsp; 2. &nbsp;XMLA scripts for creating, stopping, deleting extended events. &nbsp;(Also find these files </font><u><a href="http://www.delorabradish.com/dba/sql-server-profiler-2016-vs-extended-events-for-analysis-services-ssas-database-administration" target="_blank"><font color="#da8044">here</font></a></u><font color="#2a2a2a">.)</font><br /><font color="#2a2a2a">&nbsp;&nbsp; &nbsp; 3. &nbsp;T-SQL scripts for interpreting SSAS event data. &nbsp;(Also find these files </font><u><a href="http://www.delorabradish.com/ssas/monitoring-performance-tuning-troubleshooting-sql-server-analysis-services-ssas-2016-activity-with-extended-events" target="_blank"><font color="#e0915c">here</font></a></u><font color="#2a2a2a">.)</font><br /><font color="#2a2a2a">&nbsp;&nbsp; &nbsp; 4. &nbsp;Visual Studio Community Edition SSIS solution for warming multidimensional cache<br /><br />Thanks for coming!!</font><br /></div>  <div><div style="margin: 10px 0 0 -10px"> <a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/2017-03-07_monitoring_ssas_with_extended_events_webinar.zip"><img src="//www.weebly.com/weebly/images/file_icons/gz.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> 2017-03-07_monitoring_ssas_with_extended_events_webinar.zip</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>6779 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> zip</td></tr></table><a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/2017-03-07_monitoring_ssas_with_extended_events_webinar.zip" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>]]></content:encoded></item><item><title><![CDATA[Monitoring SQL Server Analysis Services (SSAS) 2016 Activity with Extended Events; Finding Formula and Storage Engine Durations with Extended Events]]></title><link><![CDATA[https://www.delorabradish.com/ssas/monitoring-performance-tuning-troubleshooting-sql-server-analysis-services-ssas-2016-activity-with-extended-events]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/monitoring-performance-tuning-troubleshooting-sql-server-analysis-services-ssas-2016-activity-with-extended-events#comments]]></comments><pubDate>Mon, 06 Mar 2017 14:49:16 GMT</pubDate><category><![CDATA[DBA]]></category><category><![CDATA[Extended Events]]></category><category><![CDATA[SSAS]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/monitoring-performance-tuning-troubleshooting-sql-server-analysis-services-ssas-2016-activity-with-extended-events</guid><description><![CDATA[Extended Events (EE) is a great SQL Server tool for monitoring Analysis Services, both multidimensional and tabular models. &nbsp;I use EE primarily to answer five questions about SSAS.1. &nbsp;Who is actually using our tabular models and multidimensional cubes?2. &nbsp;How often is [someone] running queries?3. &nbsp;What are my longest running queries?4. &nbsp;For multidimensional cubes, and I missing aggregations?5. &nbsp;For long-running queries, is the problem my storage or formula engine?I  [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><font color="#2a2a2a">Extended Events (EE) is a great SQL Server tool for monitoring Analysis Services, both multidimensional and tabular models. &nbsp;I use EE primarily to answer five questions about SSAS.</font><br /><font color="#2a2a2a">1. &nbsp;Who is actually using our tabular models and multidimensional cubes?</font><br /><font color="#2a2a2a">2. &nbsp;How often is [someone] running queries?</font><br /><font color="#2a2a2a">3. &nbsp;What are my longest running queries?</font><br /><font color="#2a2a2a">4. &nbsp;For multidimensional cubes, and I missing aggregations?</font><br /><font color="#2a2a2a">5. &nbsp;For long-running queries, is the problem my storage or formula engine?</font><br /><br /><font color="#2a2a2a">I also like to use EE to warm the multidimensional cache after cube processing, but that is a subject for another blog post. &nbsp;The subject of this blog post is really about interpreting data captured by EE.</font><br /><br /><strong><font color="#c2743b">Prerequisite:</font></strong><font color="#2a2a2a"> Knowledge of how to start, stop and import data from EE sessions. &nbsp;If EEs are new to you, I have a blog post on </font><u><a href="http://www.delorabradish.com/dba/sql-server-profiler-2016-vs-extended-events-for-analysis-services-ssas-database-administration" target="_blank"><font color="#e0915c">EE for Analysis Services Database Administration</font></a></u><font color="#2a2a2a"> that might be helpful. &nbsp;This blog post assumes that you have already imported EE data into a SQL Server database table and are at the point of wanting to analyze that data.</font><br /><br /><strong><font color="#c2743b">Summary</font><font color="#2a2a2a">: </font></strong><font color="#2a2a2a">If you want to jump to the finish line, download the two files I've attached to this blog post. &nbsp;They are t-sql statements that read from EE SQL Server tables for both multidimensional and tabular models returning&nbsp;login, query durations, execution counts, storage and formula engine durations. &nbsp;Enjoy!</font><br /><br /><font color="#c2743b"><strong>Detail:</strong></font><br /><font color="#2a2a2a">The most important thing to understand when reading EE data is how EE reports storage and formula engine durations. &nbsp;Very simplistically, the storage engine is exactly what you think it is -- it stores the data. &nbsp;The formula engine does the number crunching. &nbsp;The first step in SSAS query optimization is to understand where you are paying the price of the query duration.</font><br /><font color="#da8044">Multidimensional Cubes</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/published/extended-events1.png?1488836774" alt="Picture" style="width:480;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><font color="#da8044">Tabular Models</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/published/extended-events2.png?1488836862" alt="Picture" style="width:541;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph"><font color="#2a2a2a">The attached t-sql documents have this all figured out for you, but I fully expect you to take these code samples and make them your own. &nbsp;For example, group the resulting row set ordering by QueryDuration DESC, or select for one particular user Id. &nbsp;Compare the storage and formula engine durations and email a SSRS report for percentages exceeding a predetermined amount. &nbsp;Basically, <strong>use EE to </strong></font><em style="color:rgb(42, 42, 42)"><strong>be proactive</strong></em><font color="#2a2a2a"><strong> in finding long-running queries</strong> and don't wait for the help desk phone to ring.</font><br /><br /><font color="#2a2a2a">If working with <em>multidimensional </em>cubes, pay attention to the QuerySubcubeVerbose event. &nbsp;The query text will help you identify missing aggregations. &nbsp;</font><u><a href="https://www.amazon.com/Expert-Cube-Development-Multidimensional-Models/dp/1849689903" target="_blank"><font color="#da8044">Expert Cube Development with Multidimensional Models</font></a></u><font color="#2a2a2a"> will give you more information on this. &nbsp;My experience has been that once I make sure all necessary hierarchies are in place, all fact tables are partitioned properly, aggregations have updated with usage-based aggregations, and poorly written MDX has been revised, I rarely have to spend time in the QuerySubcubeVerbose event. &nbsp;However, as a matter of last resort, this event has much complicated but informative query information.</font><br /><br /><font color="#c2743b"><strong>Files for Download</strong></font></div>  <div><div style="margin: 10px 0 0 -10px"> <a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/dba_read_extended_events_for_multid_cubes.sql"><img src="//www.weebly.com/weebly/images/file_icons/file.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> dba_read_extended_events_for_multid_cubes.sql</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>2 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> sql</td></tr></table><a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/dba_read_extended_events_for_multid_cubes.sql" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>  <div><div style="margin: 10px 0 0 -10px"> <a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/dba_read_extended_events_for_tabular_models.sql"><img src="//www.weebly.com/weebly/images/file_icons/file.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> dba_read_extended_events_for_tabular_models.sql</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>1 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> sql</td></tr></table><a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/dba_read_extended_events_for_tabular_models.sql" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>]]></content:encoded></item><item><title><![CDATA[SSAS Multidimensional Cubes: Finding Actual Partition File Size on Disc]]></title><link><![CDATA[https://www.delorabradish.com/ssas/ssas-multidimensional-cubes-finding-actual-partition-file-size-on-disc]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/ssas-multidimensional-cubes-finding-actual-partition-file-size-on-disc#comments]]></comments><pubDate>Tue, 03 Jan 2017 18:18:47 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/ssas-multidimensional-cubes-finding-actual-partition-file-size-on-disc</guid><description><![CDATA[As a SSAS DBA, or even as a SSAS developer who has responsibility for partition file sizes and multidimensional cube performance considerations, knowing the actual file size of partitions on disc is critical. &nbsp;This is not 'estimated size' that you will get from $system.discover_partition_stat, that is reflected in SSMS (SQL Server Management Studio) properties, or is found in the Visual Studio project source code. &nbsp;I am talking about actual file size on physical disc. &nbsp;I recently  [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><font color="#2a2a2a">As a SSAS DBA, or even as a SSAS developer who has responsibility for partition file sizes and multidimensional cube performance considerations, knowing the actual file size of partitions on disc is critical. &nbsp;This is not 'estimated size' that you will get from $system.discover_partition_stat, that is reflected in SSMS (SQL Server Management Studio) properties, or is found in the Visual Studio project source code. &nbsp;I am talking about <strong>actual file size on physical disc</strong>. &nbsp;I recently posted a&nbsp;<a href="http://www.delorabradish.com/ssas/ssas-multidimensional-cubes-finding-actual-aggregation-size-on-disc">blog with source code&nbsp;</a>that provides t-SQL to get actual&nbsp;<strong>aggregation</strong>&nbsp;file size on disc. &nbsp;<span style="color:rgb(42, 42, 42)">With a little updating, you can use the same script to get&nbsp;</span><strong style="color:rgb(42, 42, 42)">patition</strong><span style="color:rgb(42, 42, 42)">&nbsp;file sizes. &nbsp;</span><br /><br />Note:&nbsp;Partition sizes should be at least 4 GB in size. &nbsp;Smaller, larger or unbalanced&nbsp;partitions sizes and you are risking increasing query response times and query processing.<br /><br />I hear there is a blog post showing how to get this information in Excel, but I'm a t-SQL girl and I want to use SSMS &nbsp;to get my cube metadata. &nbsp;The output of the t-SQL statement I am providing is what you see here, but with your cube and partition names:</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/partition-file-sizes1_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div><div style="margin: 10px 0 0 -10px"> <a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/dba_get_ssas_partition_file_sizes.sql"><img src="//www.weebly.com/weebly/images/file_icons/file.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> dba_get_ssas_partition_file_sizes.sql</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>8 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> sql</td></tr></table><a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/dba_get_ssas_partition_file_sizes.sql" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>  <div class="paragraph"><font color="#2a2a2a">If you are unable to download the above t-SQL file, I am pasting the source code here, but my blog service provider doesn't always format it as nicely as SSMS.<br /><br />&#8203;Enjoy!</font><br /><br /><font color="#a85f2e"><font size="2">/*<br />Script written by Delora J Bradish, www.delorabradish.com<br />Script snippet taken from http://stackoverflow.com/questions/7952406/get-each-file-size-inside-a-folder-using-sql as indicated below<br /><br />To use:<br />1. &nbsp;Change the @i_DataFileLocation to the folder location of your SSAS MultiD cube data<br />&nbsp; &nbsp; If you don't know where this is, look under [Your SSAS Instance] --&gt; Properties --&gt; General --&gt; DataDir<br />2. &nbsp;Change the @i_DatabaseId to be your database Id. &nbsp;This is NOT the database name.<br />&nbsp; &nbsp; Find you database Id by looking under [Your SSAS Instance] --&gt; [Your Deployed Database Name] --&gt; Properties --&gt; Database --&gt; ID<br />3. &nbsp;Change the @i_CubeId to be your cube Id. &nbsp;This is NOT the cube name.<br />&nbsp; &nbsp; Find your cube Id by looking under [Your SSAS Instance] --&gt; [Your SSAS Database Name] --&gt; [Your Cube Name] --&gt; Properties --&gt; General -&gt; ID<br />4. &nbsp;Set @lPrintIt to one (1) to see the detail data extracted behind the final output<br />4. &nbsp;Make sure xp_cmdshell is enabled on your SQL Server Database instance. &nbsp;You will need to be a sysadmin on your DB instance to run this t-SQL.<br /><br />&nbsp;&nbsp; &nbsp;-- To allow advanced options to be changed.<br />&nbsp;&nbsp; &nbsp;EXEC sp_configure 'show advanced options', 1<br />&nbsp;&nbsp; &nbsp;GO<br />&nbsp;&nbsp; &nbsp;-- To update the currently configured value for advanced options.<br />&nbsp;&nbsp; &nbsp;RECONFIGURE<br />&nbsp;&nbsp; &nbsp;GO<br />&nbsp;&nbsp; &nbsp;-- To enable the feature.<br />&nbsp;&nbsp; &nbsp;EXEC sp_configure 'xp_cmdshell', 1<br />&nbsp;&nbsp; &nbsp;GO<br />&nbsp;&nbsp; &nbsp;-- To update the currently configured value for this feature.<br />&nbsp;&nbsp; &nbsp;RECONFIGURE<br />&nbsp;&nbsp; &nbsp;GO<br />5. &nbsp;You will need to have read access to the physical drives where your SSAS data is stored. &nbsp;Use Windows File Explorer and make sure your AD account<br />&nbsp; &nbsp; can navigate to and see *.db, *.cub, *.det, and *.prt files.<br /><br />Note: If you receive blank output from these SELECT statements, chances are the values entered in the input variables are incorrect.<br />&nbsp; &nbsp; &nbsp; If you do not recognize the PartitionID values, you may want to drop and recreate your partitions so that their IDs match their names<br />*/<br /><br />DECLARE&nbsp;<br />&nbsp;&nbsp; &nbsp; &nbsp;@i_DataFileLocation varchar(max) = 'C:\PW_DEV\SQL Server\MSSQL\OLAP\'<br />&nbsp;&nbsp; &nbsp;, @i_DatabaseId varchar(500) = '%AW MultiD%'<br />&nbsp;&nbsp; &nbsp;, @i_CubeId varchar(100) = '%Adventure Works%'<br /><br />DECLARE&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;@lCnt&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int,<br />&nbsp;&nbsp; &nbsp;@lComm&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;varchar(1000),<br />&nbsp;&nbsp; &nbsp;@lResultString&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;varchar(max),<br />&nbsp;&nbsp; &nbsp;@lPrintIt&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int,<br />&nbsp;&nbsp; &nbsp;@lSuccess&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int,<br />&nbsp;&nbsp; &nbsp;@CurrentDirectory&nbsp;&nbsp; &nbsp;varchar(1000),<br />&nbsp;&nbsp; &nbsp;@1MB&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DECIMAL,<br />&nbsp; &nbsp; @1KB&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DECIMAL<br />&nbsp;&nbsp; &nbsp;<br />SELECT&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;@lPrintIt&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;=&nbsp;&nbsp; &nbsp;0,<br />&nbsp;&nbsp; &nbsp;@lSuccess&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;=&nbsp;&nbsp; &nbsp;0,<br />&nbsp;&nbsp; &nbsp;@1MB&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;= 1024 * 1024,<br />&nbsp;&nbsp; &nbsp;@1KB&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;= 1024<br /><br />--drop temp tables if they already exist<br />IF OBJECT_ID(N'tempdb..#DataFileList') IS NOT NULL<br />&nbsp;&nbsp; &nbsp;DROP table #DataFileList<br />IF OBJECT_ID(N'tempdb..#tempFilePaths') IS NOT NULL<br />&nbsp;&nbsp; &nbsp;DROP TABLE #tempFilePaths<br />IF OBJECT_ID(N'tempdb..#tempFileInformation') IS NOT NULL<br />&nbsp;&nbsp; &nbsp;DROP TABLE #tempFileInformation&nbsp;<br />IF OBJECT_ID(N'tempdb..#FinalOutput') IS NOT NULL<br />&nbsp;&nbsp; &nbsp;DROP TABLE #FinalOutput&nbsp;<br /><br />-- Create the temp table that will hold the data file names<br />CREATE TABLE #DataFileList(DataFileName&nbsp;&nbsp; &nbsp;varchar(max))<br />IF @@error &lt;&gt; 0 SELECT @lResultString = '1.a Unable to create #DataFileList'<br /><br />CREATE TABLE #tempFilePaths (Files VARCHAR(500))<br />IF @@error &lt;&gt; 0 SELECT @lResultString = '1.a Unable to create #tempFilePaths'<br /><br />CREATE TABLE #tempFileInformation (FilePath VARCHAR(500), FileSize VARCHAR(100))<br />IF @@error &lt;&gt; 0 SELECT @lResultString = '1.a Unable to create #tempFileInformation'<br /><br />CREATE TABLE #FinalOutput (FullPathAndFile varchar(400), NameOfFile VARCHAR(400), SizeInMB DECIMAL(13,2), SizeInKB DECIMAL(13,2))<br />IF @@error &lt;&gt; 0 SELECT @lResultString = '1.a Unable to create #FinalOutput'<br /><br />--get the list of data files<br />SELECT &nbsp;&nbsp; &nbsp;@lComm &nbsp;&nbsp; &nbsp;= 'dir "' + @i_DataFileLocation + '*.data*" /b /s'<br />INSERT #DataFileList EXEC master..xp_cmdshell @lComm<br /><br />--Clean up the list<br />DELETE FROM #DataFileList<br />WHERE DataFileName NOT LIKE '%string.data%'<br />&nbsp; AND DataFileName NOT LIKE '%fact.data%'<br /><br />DELETE FROM #DataFileList<br />WHERE DataFileName NOT LIKE '%.prt\%'<br />&nbsp; OR DataFileName LIKE '%.agg.%'<br />&nbsp; or DataFileName is NULL<br /><br />IF @lPrintIt = 1<br />&nbsp;&nbsp; &nbsp;SELECT * FROM #DataFileList<br /><br />--add an identity seed for remaining rows to use in WHILE loop<br />ALTER TABLE #DataFileList<br />ADD<br />RowNum int Identity(1,1)<br /><br />--loop through DataFileName values and get file size<br />-- from http://stackoverflow.com/questions/7952406/get-each-file-size-inside-a-folder-using-sql<br /><br />SET @lcnt = (select count(*) from #DataFileList)<br /><br />WHILE @lcnt &lt;&gt; 0<br />&nbsp;&nbsp; &nbsp;BEGIN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DECLARE @filesize INT<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SET @CurrentDirectory = (SELECT DataFileName FROM #DataFileList WHERE RowNum = @lcnt)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SET @lcomm = 'dir "' + @CurrentDirectory +'"'<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ------------------------------------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Clear the table<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE FROM #tempFilePaths<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT INTO #tempFilePaths<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EXEC MASTER..XP_CMDSHELL @lcomm&nbsp;<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --delete all directories<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE #tempFilePaths WHERE Files LIKE '%&lt;dir&gt;%'<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --delete all informational messages<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE #tempFilePaths WHERE Files LIKE ' %'<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --delete the null values<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE #tempFilePaths WHERE Files IS NULL<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --get rid of dateinfo<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPDATE #tempFilePaths SET files =RIGHT(files,(LEN(files)-20))<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --get rid of leading spaces<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPDATE #tempFilePaths SET files =LTRIM(files)<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --split data into size and filename<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ----------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Clear the table<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE FROM #tempFileInformation;<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Store the FileName &amp; Size<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT INTO #tempFileInformation<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RIGHT(files,LEN(files) -PATINDEX('% %',files)) AS FilePath,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LEFT(files,PATINDEX('% %',files)) AS FileSize<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;#tempFilePaths<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- &nbsp;Remove the commas<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPDATE &nbsp;#tempFileInformation<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SET &nbsp; &nbsp; FileSize = REPLACE(FileSize, ',','')<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Store the results in the output table<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --------------------------------------------------------------<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT INTO #FinalOutput (FullPathAndFile, NameOfFile, SizeInMB, SizeInKB)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @CurrentDirectory,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FilePath,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CAST(CAST(FileSize AS DECIMAL(13,2))/ @1MB AS DECIMAL(13,2)),<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CAST(CAST(FileSize AS DECIMAL(13,2))/ @1KB AS DECIMAL(13,2))<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;#tempFileInformation<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --------------------------------------------------------------------------------------------<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Set @lcnt = @lcnt -1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END<br /><br />&nbsp;&nbsp; &nbsp;END<br /><br />ALTER TABLE #FinalOutput<br />ADD<br />&nbsp;&nbsp; &nbsp; DatabaseID varchar(500)<br />&nbsp;&nbsp; &nbsp;,CubeID varchar(500)<br />&nbsp;&nbsp; &nbsp;,MeasureGroupID varchar(500)<br />&nbsp;&nbsp; &nbsp;,PartitionID varchar(500)<br /><br />/*<br />--Run the following script for trouble shooting undesired output<br />SELECT *<br />&nbsp;&nbsp; &nbsp;,(CHARINDEX('.det\',FullPathAndFile,1)) as EndHere<br />&nbsp;&nbsp; &nbsp;,(CHARINDEX('.cub\',FullPathAndFile,1)) as StartHere<br />&nbsp;&nbsp; &nbsp;,(CHARINDEX('.prt\',FullPathAndFile,1) + 4) - (CHARINDEX('.det\',FullPathAndFile,1) + 5)<br />&nbsp;&nbsp; &nbsp;,SUBSTRING(FullPathAndFile,CHARINDEX('.det\',FullPathAndFile,1) + 5,25)<br />&nbsp;&nbsp; &nbsp;,SUBSTRING(FullPathAndFile,CHARINDEX('.det\',FullPathAndFile,1) + 5,(CHARINDEX('.prt\',FullPathAndFile,1) + 4) - (CHARINDEX('.det\',FullPathAndFile,1) + 5))<br />FROM #FinalOutput<br />*/<br /><br />UPDATE #FinalOutput<br />SET &nbsp;DatabaseID = SUBSTRING(FullPathAndFile,LEN(@i_DataFileLocation) + 1,CHARINDEX('.db\',FullPathAndFile,1) - LEN(@i_DataFileLocation) + 2)<br />&nbsp;&nbsp; &nbsp;,CubeID = SUBSTRING(FullPathAndFile,CHARINDEX('.db\',FullPathAndFile,1) + 4,CHARINDEX('.cub\',FullPathAndFile,1) - CHARINDEX('.db\',FullPathAndFile,1))<br />&nbsp;&nbsp; &nbsp;,MeasureGroupID = SUBSTRING(FullPathAndFile,CHARINDEX('.cub\',FullPathAndFile,1) + 5,CHARINDEX('.det\',FullPathAndFile,1) - CHARINDEX('cub\',FullPathAndFile,1))<br />&nbsp;&nbsp; &nbsp;,PartitionID = SUBSTRING(FullPathAndFile,CHARINDEX('.det\',FullPathAndFile,1) + 5,(CHARINDEX('.prt\',FullPathAndFile,1) + 4) - (CHARINDEX('.det\',FullPathAndFile,1) + 5))<br />&nbsp;&nbsp; &nbsp;<br />IF @lPrintIt = 1<br />&nbsp;&nbsp; &nbsp;SELECT * FROM #FinalOutput WHERE DatabaseID like @i_DatabaseId<br /><br />--get total partition sizes on disc<br />select&nbsp;<br />&nbsp;&nbsp; &nbsp; DatabaseID<br />&nbsp;&nbsp; &nbsp;,CubeID<br />&nbsp;&nbsp; &nbsp;,MeasureGroupID<br />&nbsp;&nbsp; &nbsp;,PartitionID<br />&nbsp;&nbsp; &nbsp;,SumOfSizeInKB = SUM(SizeInKB)<br />&nbsp;&nbsp; &nbsp;,SumOfSizeInMB = SUM(SizeInMB)&nbsp;<br />&nbsp;&nbsp; &nbsp;,SumOfSizeInGB = SUM(SizeInMB) / 1000<br />FROM #FinalOutput<br />WHERE DatabaseID like @i_DatabaseId AND CubeID like @i_CubeId<br />GROUP BY DatabaseID, CubeID, MeasureGroupID, PartitionID<br />ORDER BY DatabaseID, CubeID, MeasureGroupID, PartitionID<br /><br />RETURN</font></font><br /><br /></div>]]></content:encoded></item><item><title><![CDATA[SSAS Multidimensional Cubes: Finding Actual Aggregation Size on Disc]]></title><link><![CDATA[https://www.delorabradish.com/ssas/ssas-multidimensional-cubes-finding-actual-aggregation-size-on-disc]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/ssas-multidimensional-cubes-finding-actual-aggregation-size-on-disc#comments]]></comments><pubDate>Tue, 03 Jan 2017 18:17:50 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/ssas-multidimensional-cubes-finding-actual-aggregation-size-on-disc</guid><description><![CDATA[I recently posted a blog with source code that provides t-SQL to get actual partition file size on disc. &nbsp;With a little updating, you can use the same script to get aggregation file sizes. &nbsp;&#8203;Why do we care?1. Aggregations are a shortcut to acquiring a SUM() or a COUNT() of a measure. &nbsp;Think of aggregations as pre-calculated totals.2. &nbsp;Correctly designed aggregations have a direct and SIGNIFICANT influence on end-user query performance.3. &nbsp;Aggregations&nbsp;are not  [...] ]]></description><content:encoded><![CDATA[<div class="paragraph"><font color="#2a2a2a">I recently posted a</font> <a href="http://www.delorabradish.com/ssas/ssas-multidimensional-cubes-finding-actual-partition-file-size-on-disc">blog with source code</a> <font color="#2a2a2a">that provides t-SQL to get actual<strong> partition</strong> file size on disc. &nbsp;With a little updating, you can use the same script to get <strong>aggregation</strong> file sizes. &nbsp;<br /><br />&#8203;Why do we care?<br />1. Aggregations are a shortcut to acquiring a SUM() or a COUNT() of a measure. &nbsp;Think of aggregations as pre-calculated totals.<br /><br />2. &nbsp;Correctly designed aggregations have a direct and SIGNIFICANT influence on end-user query performance.<br /><br />3. &nbsp;Aggregations&nbsp;are not automatic. &nbsp;You must create them in the cube on the Aggregations tab, and as a general rule of thumb, <strong>aggregations should not exceed 30% of partition size</strong>. &nbsp;<br /><br />4.&nbsp;Monitoring partition and aggregation file sizes is an on-going effort and it is often the place where multidimensional&nbsp;cubes "fall down" -- no one is paying attention. &nbsp;Developers move on to new projects, and even large companies often do not have dedicated SSAS DBAs. &nbsp;However, this can be an easy win if given an Outlook calendar reminder and a little effort.<br /><br />Reminder:&nbsp;<strong>Each partition can only have one (1) active aggregation design</strong>; however, because a measure group can have &gt; 1 partition, measure groups can have &gt; 1 aggregation design.<br /><br /><span style="color:rgb(42, 42, 42)">The output of the t-SQL statement I am providing is what you see here, but with your cube and partition names:</span></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/aggregation-file-sizes1_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div><div style="margin: 10px 0 0 -10px"> <a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/dba_get_ssas_aggregation_file_sizes.sql"><img src="//www.weebly.com/weebly/images/file_icons/file.png" width="36" height="36" style="float: left; position: relative; left: 0px; top: 0px; margin: 0 15px 15px 0; border: 0;" /></a><div style="float: left; text-align: left; position: relative;"><table style="font-size: 12px; font-family: tahoma; line-height: .9;"><tr><td colspan="2"><b> dba_get_ssas_aggregation_file_sizes.sql</b></td></tr><tr style="display: none;"><td>File Size:  </td><td>8 kb</td></tr><tr style="display: none;"><td>File Type:  </td><td> sql</td></tr></table><a href="https://www.delorabradish.com/uploads/5/3/4/3/53431729/dba_get_ssas_aggregation_file_sizes.sql" style="font-weight: bold;">Download File</a></div> </div>  <hr style="clear: both; width: 100%; visibility: hidden"></hr></div>  <div class="paragraph"><span style="color:rgb(42, 42, 42)">&nbsp;If you are unable to download the above t-SQL file, I am pasting the source code here, but my blog service provider doesn't always format it as nicely as SSMS.</span><br /><br /><span style="color:rgb(42, 42, 42)">&#8203;Enjoy!<br /><br /></span><font color="#a85f2e"><font size="2">/*<br />Script written by Delora J Bradish, www.delorabradish.com<br />Script snippet taken from http://stackoverflow.com/questions/7952406/get-each-file-size-inside-a-folder-using-sql as indicated below<br /><br />To use:<br />1. &nbsp;Change the @i_DataFileLocation to the folder location of your SSAS MultiD cube data<br />&nbsp; &nbsp; If you don't know where this is, look under [Your SSAS Instance] --&gt; Properties --&gt; General --&gt; DataDir<br />2. &nbsp;Change the @i_DatabaseId to be your database Id. &nbsp;This is NOT the database name.<br />&nbsp; &nbsp; Find you database Id by looking under [Your SSAS Instance] --&gt; [Your Deployed Database Name] --&gt; Properties --&gt; Database --&gt; ID<br />3. &nbsp;Change the @i_CubeId to be your cube Id. &nbsp;This is NOT the cube name.<br />&nbsp; &nbsp; Find your cube Id by looking under [Your SSAS Instance] --&gt; [Your SSAS Database Name] --&gt; [Your Cube Name] --&gt; Properties --&gt; General -&gt; ID<br />4. &nbsp;Set @lPrintIt to one (1) to see the detail data extracted behind the final output<br />4. &nbsp;Make sure xp_cmdshell is enabled on your SQL Server Database instance. &nbsp;You will need to be a sysadmin on your DB instance to run this t-SQL.<br /><br />&nbsp;&nbsp; &nbsp;-- To allow advanced options to be changed.<br />&nbsp;&nbsp; &nbsp;EXEC sp_configure 'show advanced options', 1<br />&nbsp;&nbsp; &nbsp;GO<br />&nbsp;&nbsp; &nbsp;-- To update the currently configured value for advanced options.<br />&nbsp;&nbsp; &nbsp;RECONFIGURE<br />&nbsp;&nbsp; &nbsp;GO<br />&nbsp;&nbsp; &nbsp;-- To enable the feature.<br />&nbsp;&nbsp; &nbsp;EXEC sp_configure 'xp_cmdshell', 1<br />&nbsp;&nbsp; &nbsp;GO<br />&nbsp;&nbsp; &nbsp;-- To update the currently configured value for this feature.<br />&nbsp;&nbsp; &nbsp;RECONFIGURE<br />&nbsp;&nbsp; &nbsp;GO<br />5. &nbsp;You will need to have read access to the physical drives where your SSAS data is stored. &nbsp;Use Windows File Explorer and make sure your AD account<br />&nbsp; &nbsp; can navigate to and see *.db, *.cub, *.det, and *.prt files.<br /><br />Note: If you receive blank output from these SELECT statements, chances are the values entered in the input variables are incorrect.<br />&nbsp; &nbsp; &nbsp; If you do not recognize the PartitionID values, you may want to drop and recreate your partitions so that their IDs match their names<br />&nbsp;&nbsp; &nbsp; &nbsp;Remember that SSAS only allows one (1) active aggregation design for each partition.<br />*/<br /><br />DECLARE&nbsp;<br />&nbsp;&nbsp; &nbsp; &nbsp;@i_DataFileLocation varchar(max) = 'C:\PW_DEV\SQL Server\MSSQL\OLAP\'<br />&nbsp;&nbsp; &nbsp;, @i_DatabaseId varchar(500) = '%AW MultiD%'<br />&nbsp;&nbsp; &nbsp;, @i_CubeId varchar(100) = '%Adventure Works%'<br /><br />DECLARE&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;@lCnt&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int,<br />&nbsp;&nbsp; &nbsp;@lComm&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;varchar(1000),<br />&nbsp;&nbsp; &nbsp;@lResultString&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;varchar(max),<br />&nbsp;&nbsp; &nbsp;@lPrintIt&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int,<br />&nbsp;&nbsp; &nbsp;@lSuccess&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int,<br />&nbsp;&nbsp; &nbsp;@CurrentDirectory&nbsp;&nbsp; &nbsp;varchar(1000),<br />&nbsp;&nbsp; &nbsp;@1MB&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DECIMAL,<br />&nbsp; &nbsp; @1KB&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DECIMAL<br />&nbsp;&nbsp; &nbsp;<br />SELECT&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;@lPrintIt&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;=&nbsp;&nbsp; &nbsp;0,<br />&nbsp;&nbsp; &nbsp;@lSuccess&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;=&nbsp;&nbsp; &nbsp;0,<br />&nbsp;&nbsp; &nbsp;@1MB&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;= 1024 * 1024,<br />&nbsp;&nbsp; &nbsp;@1KB&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;= 1024<br /><br />--drop temp tables if they already exist<br />IF OBJECT_ID(N'tempdb..#DataFileList') IS NOT NULL<br />&nbsp;&nbsp; &nbsp;DROP table #DataFileList<br />IF OBJECT_ID(N'tempdb..#tempFilePaths') IS NOT NULL<br />&nbsp;&nbsp; &nbsp;DROP TABLE #tempFilePaths<br />IF OBJECT_ID(N'tempdb..#tempFileInformation') IS NOT NULL<br />&nbsp;&nbsp; &nbsp;DROP TABLE #tempFileInformation&nbsp;<br />IF OBJECT_ID(N'tempdb..#FinalOutput') IS NOT NULL<br />&nbsp;&nbsp; &nbsp;DROP TABLE #FinalOutput&nbsp;<br /><br />-- Create the temp table that will hold the data file names<br />CREATE TABLE #DataFileList(DataFileName&nbsp;&nbsp; &nbsp;varchar(max))<br />IF @@error &lt;&gt; 0 SELECT @lResultString = '1.a Unable to create #DataFileList'<br /><br />CREATE TABLE #tempFilePaths (Files VARCHAR(500))<br />IF @@error &lt;&gt; 0 SELECT @lResultString = '1.a Unable to create #tempFilePaths'<br /><br />CREATE TABLE #tempFileInformation (FilePath VARCHAR(500), FileSize VARCHAR(100))<br />IF @@error &lt;&gt; 0 SELECT @lResultString = '1.a Unable to create #tempFileInformation'<br /><br />CREATE TABLE #FinalOutput (FullPathAndFile varchar(400), NameOfFile VARCHAR(400), SizeInMB DECIMAL(13,2), SizeInKB DECIMAL(13,2))<br />IF @@error &lt;&gt; 0 SELECT @lResultString = '1.a Unable to create #FinalOutput'<br /><br />--get the list of data files<br />SELECT &nbsp;&nbsp; &nbsp;@lComm &nbsp;&nbsp; &nbsp;= 'dir "' + @i_DataFileLocation + '*.data*" /b /s'<br />INSERT #DataFileList EXEC master..xp_cmdshell @lComm<br /><br />--Clean up the list<br />DELETE FROM #DataFileList<br />WHERE DataFileName NOT LIKE '%.agg%'<br /><br />IF @lPrintIt = 1<br />&nbsp;&nbsp; &nbsp;SELECT * FROM #DataFileList<br /><br />--add an identity seed for remaining rows to use in WHILE loop<br />ALTER TABLE #DataFileList<br />ADD<br />RowNum int Identity(1,1)<br /><br />--loop through DataFileName values and get file size<br />-- from http://stackoverflow.com/questions/7952406/get-each-file-size-inside-a-folder-using-sql<br /><br />SET @lcnt = (select count(*) from #DataFileList)<br /><br />WHILE @lcnt &lt;&gt; 0<br />&nbsp;&nbsp; &nbsp;BEGIN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DECLARE @filesize INT<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SET @CurrentDirectory = (SELECT DataFileName FROM #DataFileList WHERE RowNum = @lcnt)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SET @lcomm = 'dir "' + @CurrentDirectory +'"'<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ------------------------------------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Clear the table<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE FROM #tempFilePaths<br /><br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT INTO #tempFilePaths<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EXEC MASTER..XP_CMDSHELL @lcomm&nbsp;<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --delete all directories<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE #tempFilePaths WHERE Files LIKE '%&lt;dir&gt;%'<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --delete all informational messages<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE #tempFilePaths WHERE Files LIKE ' %'<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --delete the null values<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE #tempFilePaths WHERE Files IS NULL<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --get rid of dateinfo<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPDATE #tempFilePaths SET files =RIGHT(files,(LEN(files)-20))<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --get rid of leading spaces<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPDATE #tempFilePaths SET files =LTRIM(files)<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --split data into size and filename<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ----------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Clear the table<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DELETE FROM #tempFileInformation;<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Store the FileName &amp; Size<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT INTO #tempFileInformation<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RIGHT(files,LEN(files) -PATINDEX('% %',files)) AS FilePath,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LEFT(files,PATINDEX('% %',files)) AS FileSize<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;#tempFilePaths<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- &nbsp;Remove the commas<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPDATE &nbsp;#tempFileInformation<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SET &nbsp; &nbsp; FileSize = REPLACE(FileSize, ',','')<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Store the results in the output table<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --------------------------------------------------------------<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT INTO #FinalOutput (FullPathAndFile, NameOfFile, SizeInMB, SizeInKB)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @CurrentDirectory,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FilePath,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CAST(CAST(FileSize AS DECIMAL(13,2))/ @1MB AS DECIMAL(13,2)),<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CAST(CAST(FileSize AS DECIMAL(13,2))/ @1KB AS DECIMAL(13,2))<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;#tempFileInformation<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --------------------------------------------------------------------------------------------<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Set @lcnt = @lcnt -1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END<br /><br />&nbsp;&nbsp; &nbsp;END<br /><br />ALTER TABLE #FinalOutput<br />ADD<br />&nbsp;&nbsp; &nbsp; DatabaseID varchar(500)<br />&nbsp;&nbsp; &nbsp;,CubeID varchar(500)<br />&nbsp;&nbsp; &nbsp;,MeasureGroupID varchar(500)<br />&nbsp;&nbsp; &nbsp;,PartitionId varchar(500)<br />&nbsp;&nbsp; &nbsp;,AggregationID varchar(500)<br /><br />/*<br />--Run the following script for trouble shooting undesired output<br />SELECT *<br />&nbsp;&nbsp; &nbsp;,(CHARINDEX('.det\',FullPathAndFile,1)) as EndHere<br />&nbsp;&nbsp; &nbsp;,(CHARINDEX('.cub\',FullPathAndFile,1)) as StartHere<br />&nbsp;&nbsp; &nbsp;,(CHARINDEX('.prt\',FullPathAndFile,1) + 4) - (CHARINDEX('.det\',FullPathAndFile,1) + 5)<br />&nbsp;&nbsp; &nbsp;,SUBSTRING(FullPathAndFile,CHARINDEX('.det\',FullPathAndFile,1) + 5,25)<br />&nbsp;&nbsp; &nbsp;,SUBSTRING(FullPathAndFile,CHARINDEX('.det\',FullPathAndFile,1) + 5,(CHARINDEX('.prt\',FullPathAndFile,1) + 4) - (CHARINDEX('.det\',FullPathAndFile,1) + 5))<br />FROM #FinalOutput<br />*/<br /><br />UPDATE #FinalOutput<br />SET &nbsp;DatabaseID = SUBSTRING(FullPathAndFile,LEN(@i_DataFileLocation) + 1,CHARINDEX('.db\',FullPathAndFile,1) - LEN(@i_DataFileLocation) + 2)<br />&nbsp;&nbsp; &nbsp;,CubeID = SUBSTRING(FullPathAndFile,CHARINDEX('.db\',FullPathAndFile,1) + 4,CHARINDEX('.cub\',FullPathAndFile,1) - CHARINDEX('.db\',FullPathAndFile,1))<br />&nbsp;&nbsp; &nbsp;,MeasureGroupID = SUBSTRING(FullPathAndFile,CHARINDEX('.cub\',FullPathAndFile,1) + 5,CHARINDEX('.det\',FullPathAndFile,1) - CHARINDEX('cub\',FullPathAndFile,1))<br />&nbsp;&nbsp; &nbsp;,PartitionID = SUBSTRING(FullPathAndFile,CHARINDEX('.det\',FullPathAndFile,1) + 5,(CHARINDEX('.prt\',FullPathAndFile,1) + 4) - (CHARINDEX('.det\',FullPathAndFile,1) + 5))<br />&nbsp;&nbsp; &nbsp;,AggregationID = SUBSTRING(FullPathAndFile,CHARINDEX('.prt\',FullPathAndFile,1) + 5,250)<br />&nbsp;&nbsp; &nbsp;<br />IF @lPrintIt = 1<br />&nbsp;&nbsp; &nbsp;SELECT * FROM #FinalOutput WHERE DatabaseID like @i_DatabaseId<br /><br />--get total partition sizes on disc<br />select&nbsp;<br />&nbsp;&nbsp; &nbsp; DatabaseID<br />&nbsp;&nbsp; &nbsp;,CubeID<br />&nbsp;&nbsp; &nbsp;,MeasureGroupID<br />&nbsp;&nbsp; &nbsp;,PartitionID<br />&nbsp;&nbsp; &nbsp;,SumOfAggSizeInKB = SUM(SizeInKB)<br />&nbsp;&nbsp; &nbsp;,SumOfAggSizeInMB = SUM(SizeInMB)&nbsp;<br />&nbsp;&nbsp; &nbsp;,SumOfAggSizeInGB = SUM(SizeInMB) / 1000<br />FROM #FinalOutput<br />WHERE DatabaseID like @i_DatabaseId AND CubeID like @i_CubeId<br />GROUP BY DatabaseID, CubeID, MeasureGroupID, PartitionID<br />ORDER BY DatabaseID, CubeID, MeasureGroupID, PartitionID<br /><br />return</font></font><br><span style="color:rgb(42, 42, 42)"></span><br /></div>]]></content:encoded></item><item><title><![CDATA[Time Calculations: Formatting percentage calculations in multidimensional cubes]]></title><link><![CDATA[https://www.delorabradish.com/ssas/time-calculations-formatting-percentage-calculations-in-multidimensional-cubes]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/time-calculations-formatting-percentage-calculations-in-multidimensional-cubes#comments]]></comments><pubDate>Sun, 17 Jan 2016 23:19:47 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/time-calculations-formatting-percentage-calculations-in-multidimensional-cubes</guid><description><![CDATA[I received this little tip from a colleague and thought I'd pass it on hoping to be of help to someone else.Problem: Dynamic time calculations in multidimensional cubes are not by nature formatted. &nbsp;It would be nice to at least return percent time calculations as percentages.Problem Illustrated: In the screen print below, [Prior Period % Change], [YTD % Change] ... columns are presented in a pivot table by default without a percentage sign.         Desired Result:&nbsp;Automatically format& [...] ]]></description><content:encoded><![CDATA[<div class="paragraph" style="text-align:left;"><font color="#2a2a2a">I received this little tip from a colleague and thought I'd pass it on hoping to be of help to someone else.</font><br /><br /><font color="#a85f2e"><strong>Problem:</strong> </font><font color="#2a2a2a">Dynamic time calculations in multidimensional cubes are not by nature formatted. &nbsp;It would be nice to at least return percent time calculations as percentages.</font><br /><br /><strong><font color="#a85f2e">Problem Illustrated:</font> </strong><font color="#2a2a2a">In the screen print below, [Prior Period % Change], [YTD % Change] ... columns are presented in a pivot table by default without a percentage sign.</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/3270467_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#a85f2e" style="font-weight: bold;">Desired Result:</font>&nbsp;<font color="#2a2a2a">Automatically format</font><font color="#2a2a2a">&nbsp;percentage calculations appearing in a pivot table with a percentage sign.</font><br /><br /><strong><font color="#a85f2e">Assumption: </font></strong><font color="#2a2a2a">You are familiar with creating MDX time calculations that can be applied against any measure in a multidimensional cube.</font><br /><br /><strong><font color="#a85f2e">Solution</font></strong><strong><font color="#a85f2e">:</font>&nbsp;</strong><font color="#2a2a2a">Scope for your percentage time calcs at the end of your MDX script, and format them as a percent.</font><br /><font color="#508d24">--format percentages</font><br /><font color="#508d24">SCOPE</font><font color="#2a2a2a">(</font><br /><font color="#2a2a2a">&nbsp; &nbsp; {[Date Calculations].[Date Calculation Name].[Prior Period % Change],</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[YTD % Change],</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[QTD % Change from Prior Year],</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[QTD % Change from Prior Quarter],</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[MTD % Change from Prior Year],</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[MTD % Change from Prior Month],</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[WTD % Change from Prior Year],</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[WTD % Change from Prior Week]}</font><br /><font color="#2a2a2a">&nbsp; &nbsp; );</font><br /><font color="#2a2a2a">&nbsp; &nbsp; </font><font color="#508d24">THIS</font><font color="#2a2a2a"> = ([Measures].currentmember);</font><br /><font color="#2a2a2a">&nbsp; &nbsp; </font><font color="#508d24">FORMAT_STRING</font><font color="#2a2a2a">(</font><font color="#508d24">this</font><font color="#2a2a2a">)="Percent";</font><br /><font color="#508d24">END SCOPE</font><font color="#2a2a2a">;</font><br /><br /><font color="#a85f2e" style="font-weight:bold">Result Illustrated: </font><font color="#2a2a2a"><strong>&nbsp;</strong>Without having to format the percentage calculation columns or rows in Excel, they will come in formatted when selected from PivotTable Fields.&nbsp;</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/8796517_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><strong style="color: rgb(168, 95, 46);">Important Note!! </strong><font color="#a85f2e">&nbsp;</font><font color="#2a2a2a">This only works with NEW &nbsp;pivot tables. &nbsp;If your pivot table or chart has already been created, doing a &lt;Data Ribbon --&gt; Refresh&gt; in Excel will not update the formatting. &nbsp;You'll see your new MDX work when you &lt;Insert&gt; new.<br /></font><br /><strong style="color: rgb(168, 95, 46);">Detail MDX Script Illustrated:</strong><br /><font color="#508d24">SCOPE</font><font color="#2a2a2a"> ([Date Default].[Y-Q-M-D Hier].</font><font color="#508d24">MEMBERS</font><font color="#2a2a2a">); &nbsp;</font><br /><font color="#508d24">--YEAR CALCULATIONS<br />&nbsp; &nbsp; --Year To Date</font><br /><font color="#2a2a2a"><br />&nbsp; &nbsp; [Date Calculations].[Date Calculation Name].[YTD] =<br />&nbsp; &nbsp; &nbsp;AGGREGATE<br />&nbsp; &nbsp; &nbsp;(<br />&nbsp; &nbsp; &nbsp; &nbsp; {[Date Calculations].[Date Calculation Name].[Current Period]} *<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PERIODSTODATE<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [Date Default].[Y-Q-M-D Hier].[Year],<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [Date Default].[Y-Q-M-D Hier].CURRENTMEMBER<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br />&nbsp; &nbsp; &nbsp;); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</font><br /><br /><font color="#508d24">&nbsp; &nbsp; --Year to Date Prior Year</font><br /><font color="#2a2a2a">&nbsp; &nbsp; [Date Calculations].[Date Calculation Name].[YTD Prior Year] =<br />&nbsp; &nbsp; &nbsp;AGGREGATE<br />&nbsp; &nbsp; &nbsp;(<br />&nbsp; &nbsp; &nbsp; &nbsp; {[Date Calculations].[Date Calculation Name].[Current Period]} *<br />&nbsp; &nbsp; &nbsp; &nbsp; PERIODSTODATE<br />&nbsp; &nbsp; &nbsp; &nbsp; (<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[Date Default].[Y-Q-M-D Hier].[Year],<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PARALLELPERIOD<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [Date Default].[Y-Q-M-D Hier].[Year],<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [Date Default].[Y-Q-M-D Hier].CURRENTMEMBER<br />&nbsp; &nbsp; &nbsp; &nbsp; )<br />&nbsp; &nbsp; &nbsp;)<br />&nbsp; &nbsp; &nbsp;); &nbsp;</font><br /><font color="#508d24">END SCOPE;&nbsp;<br /><br />--PRIOR PERIOD &amp; YEAR</font><br /><font color="#508d24">&nbsp; &nbsp; --Prior Period</font><br /><font color="#2a2a2a">&nbsp; &nbsp; [Date Calculations].[Date Calculation Name].[Prior Period]=<br />&nbsp; &nbsp; AGGREGATE<br />&nbsp; &nbsp; &nbsp; &nbsp; ([Date Default].[Y-Q-M-D Hier].CurrentMember.PrevMember,<br />&nbsp; &nbsp; &nbsp; &nbsp; [Date Calculations].[Date Calculation Name].[Current Period]); &nbsp;</font><br /><br /><font color="#508d24">&#8203;--calculate change</font><br /><font color="#2a2a2a">[Date Calculations].[Date Calculation Name].[Prior Period Change] =&nbsp;<br />&nbsp; &nbsp; [Date Calculations].[Current Period] - [Date Calculations].[Prior Period]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<br /><br />[Date Calculations].[Date Calculation Name].[YTD Change] =&nbsp;<br />&nbsp; &nbsp; [Date Calculations].[YTD] - [Date Calculations].[YTD Prior Year]; &nbsp;</font><br /><br /><br /><font color="#508d24">--calculate % change</font><br /><font color="#2a2a2a">[Date Calculations].[Date Calculation Name].[Prior Period % Change] =&nbsp;<br />&nbsp; &nbsp; DIVIDE (([Date Calculations].[Date Calculation Name].[Current Period] - [Date Calculations].[Date Calculation Name].[Prior Period]),&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[Prior Period],0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br /><br />[Date Calculations].[Date Calculation Name].[YTD % Change] =&nbsp;<br />&nbsp; &nbsp; DIVIDE (([Date Calculations].[Date Calculation Name].[YTD] - [Date Calculations].[Date Calculation Name].[YTD Prior Year]),&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[YTD Prior Year],0); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</font><br /><br /><font color="#508d24">--format percentages</font><br /><font color="#2a2a2a">SCOPE(</font><br /><font color="#2a2a2a">&nbsp; &nbsp; {[Date Calculations].[Date Calculation Name].[Prior Period % Change],</font><br /><font color="#2a2a2a">&nbsp; &nbsp; &nbsp;[Date Calculations].[Date Calculation Name].[YTD % Change]}</font><br /><font color="#2a2a2a">&nbsp; &nbsp; );</font><br /><font color="#2a2a2a">&nbsp; &nbsp; </font><font color="#508d24">THIS</font><font color="#2a2a2a"> = ([Measures].currentmember);</font><br /><font color="#2a2a2a">&nbsp; &nbsp; </font><font color="#508d24">FORMAT_STRING</font><font color="#2a2a2a">(</font><font color="#508d24">this</font><font color="#2a2a2a">)="Percent";</font><br /><font color="#508d24">END SCOPE</font><font color="#2a2a2a">;</font></div>]]></content:encoded></item><item><title><![CDATA[How to extract a list of attributes from a SSAS multidi﻿mensional cube without using a measure]]></title><link><![CDATA[https://www.delorabradish.com/ssas/how-to-extract-a-list-of-attributes-from-a-ssas-multidimensional-cube-without-using-a-measure]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/how-to-extract-a-list-of-attributes-from-a-ssas-multidimensional-cube-without-using-a-measure#comments]]></comments><pubDate>Thu, 03 Dec 2015 03:06:32 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/how-to-extract-a-list-of-attributes-from-a-ssas-multidimensional-cube-without-using-a-measure</guid><description><![CDATA[Often consumers of a SSAS multidimensional cube will want a list of attributes from the cube without having to select a measure. &nbsp; Recently, users I've been working with have wanted to do three things:Get a list of attributes in an Excel pivot table to use for lookupGet a list of attributes in PowerPivot for Excel to use for relationshipsGet a list of attributes to populate a SSRS drop down pick listIt is a misunderstanding to think that you always need a measure to get a list of attributes [...] ]]></description><content:encoded><![CDATA[<div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Often consumers of a SSAS multidimensional cube will want a list of attributes from the cube without having to select a measure. &nbsp; Recently, users I've been working with have wanted to do three things:</font><ol><li><font color="#2a2a2a">Get a list of attributes in an Excel pivot table to use for lookup</font></li><li><font color="#2a2a2a">Get a list of attributes in PowerPivot for Excel to use for relationships</font></li><li><font color="#2a2a2a">Get a list of attributes to populate a SSRS drop down pick list</font></li></ol><font color="#2a2a2a">It is a misunderstanding to think that you always need a measure to get a list of attributes from a MultiD cube.</font><br /><br /><font color="#2a2a2a"><strong>Assumption: </strong>The reader of this post knows how to create a data connection in Excel to a SSAS MultiD cube, and is familiar with creating datasets in SSRS.</font><br /><br /><font color="#da8044" size="4"><strong>Get a List of Attributes in an Excel Pivot Table:</strong></font><br /><font color="#2a2a2a">Be default, Excel will display a list of attributes when no measure is selected. &nbsp;Simply create a new pivot table and place an attribute on <strong>Rows</strong> leaving <strong>Filters</strong>, <strong>Columns</strong> and <strong>Values</strong> empty.</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/3278955.png?454" alt="Picture" style="width:454;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Depending on your cube design, you may need to change the properties of the pivot table to <strong>Show items with no data on rows</strong>. &nbsp;(You wouldn't think this should make a difference when there is no measure selected for the pivot, but it does.)</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/4371885.png?354" alt="Picture" style="width:354;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><span><font color="#da8044"><strong><font size="4">Get a List of Attributes in PowerPivot for Excel:</font></strong></font><br /><font color="#2a2a2a">The tiny trick here is to know about the <strong>Show Empty Cells </strong>button found in the <strong>Table Import Wizard</strong> screen. &nbsp;Without the <strong>Show Empty Cell</strong>s button clicked, you will receive a <strong>No rows found. Click to execute the query</strong> message.</font></span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/8943866.png?481" alt="Picture" style="width:481;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Click the <strong>Show Empty Cells</strong> button, and you will get a list of dimension attribute values without a measure.</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/9465325.png?479" alt="Picture" style="width:479;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">The result is a list of dimension attribute(s) in a PowerPivot table with no measure needed.</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/7995118.png?304" alt="Picture" style="width:304;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#da8044" size="4"><strong>Get a List of Attributes in SSRS</strong></font><br /><font color="#2a2a2a">Acquiring a list of attribute values in SSRS is a bit more challenging because you need a bit of MDX, but never fear -- take my MDX given below and make it your own.</font><br /><br /><font color="#2a2a2a">First, I strongly recommend the use of </font><font color="#2a2a2a"><strong>Shared Datasets</strong></font><font color="#2a2a2a"> in SSRS when selecting data in SSRS that could be used by more than one report. &nbsp;Data sources for drop down pick lists are excellent reasons to create a shared dataset: &nbsp;a list of relative dates, codes, descriptions, doctor names, procedures, products etc.</font><br /><br /><font color="#2a2a2a">In SSRS </font><font color="#2a2a2a"><strong>Query Designer</strong></font><font color="#2a2a2a">, copy and paste the following MDX, or your variation thereof.</font><br /><br /><font color="#da8044"><font size="1">&nbsp;SELECT {} on 0,<br />[Date].[Calendar].[Date].Members ON 1<br />FROM [Adventure Works]</font></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/4226410.png?371" alt="Picture" style="width:371;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#da8044"><font size="1">WITH MEMBER [Measures].[Level Name] as [Date].[Calendar].CurrentMember.Level.Name<br />&nbsp; &nbsp; &nbsp;MEMBER [Measures].[Ordinal No] as [Date].[Calendar].CurrentMember.Level.Ordinal<br />SELECT {[Measures].[Level Name], [Measures].[Ordinal No]} on Columns<br />&nbsp;&nbsp; &nbsp;,NON EMPTY [Date].[Calendar].members on Rows<br />FROM [Adventure Works]</font></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/8038159.png?472" alt="Picture" style="width:472;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#da8044"><font size="1">&nbsp;SELECT &nbsp;{ } &nbsp;on 0,<br />[Customer].[Education].Children on 1<br />FROM [Adventure Works]</font></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/2834733.png?110" alt="Picture" style="width:110;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">The following MDX uses a [Date Filters] table created specifically for SSRS parameters. &nbsp;Like [Date Calculations], it has no relationship to any measure group in the cube. &nbsp;The t-SQL in the cube DSV looks like this --&gt;</font><br /><font size="1"><font color="#da8044">SELECT 1 as DateFilterKey, 'CurrentDateTime' as DateFilterName, Convert(varchar(25),GetDate(),120) as DateFilterValue</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 2, 'CurrentDate' as DateCalculationName, Convert(varchar(25),Convert(Date,GetDate()),110)</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 3, 'CurrentDayNo', Convert(varchar(2),Day(GetDate()))</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 4, 'CurrentWeekNo', Convert(varchar(2),DatePart(Week, GetDate()))</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 5, 'CurrentMonthNo', Convert(varchar(2),Month(GetDate()))</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 6, 'CurrentYearMonthNo', Convert(char(6),Convert(int,Convert(char(4),Year(GetDate())) + RIGHT(RTrim('00' + Convert(char(2),Month(GetDate()))),2)))</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 7, 'PriorDay1', Convert(varchar(25),Convert(DateTime,Convert(varchar(8),GetDate() -1,112),1),110)</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 8, 'PriorWeekNo', Convert(varchar(2),DatePart(Week, GetDate() - 7))</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 9, 'PriorMonthNo', Convert(varchar(2),DatePart(mm,dateadd(day,(day(GetDate())-1)*-1,dateadd(month,-1,GetDate()))))</font><br /><font color="#da8044">UNION</font><br /><font color="#da8044">SELECT 10, 'SameDayLastYear', Convert(varchar(25),</font><br /><font color="#da8044">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;CASE WHEN Right(Convert(char(8),GetDate(),112),4) = '0229'</font><br /><font color="#da8044">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;THEN GetDate() - 366</font><br /><font color="#da8044">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;ELSE GetDate() - 365</font><br /><font color="#da8044">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;END,110)</font><br /><font color="#da8044">UNION</font></font><br /><font color="#da8044"><font size="1">SELECT 11, 'None', '01-01-2054'</font></font><br /><font color="#2a2a2a">Find a more extensive list of t-SQL data calculations <a href="http://www.delorabradish.com/dba/t-sql-date-calculations">here</a>&nbsp;--&gt; http://www.delorabradish.com/dba/t-sql-date-calculations.<br /><br />The MDX in SSRS' <strong>Query Designer</strong> is this --&gt;</font><br /><font color="#da8044"><font size="1">//get all values returned in string format<br />SELECT {} on 0,<br />([Date Filters].[Date Filter Name].Children,<br />&nbsp;[Date Filters].[Date Filter Value].Children) ON 1<br />FROM [Time Calc POC]</font></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/2815840.png?238" alt="Picture" style="width:238;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">If you just want date data types for your pick list and you have used naming conventions in your [Date Filter Name] attribute, your MDX would be as follows:</font><br /><font color="#da8044"><font size="1">//get filter values that are of a date data type only<br />SELECT {} on 0,<br />{<br />&nbsp;FILTER([Date Filters].[Date Filter Name].Children,<br />&nbsp;&nbsp; &nbsp;Right([Date Filters].[Date Filter Name].CurrentMember.Name,2) &lt;&gt; 'No'<br />&nbsp;&nbsp; &nbsp;) *<br />&nbsp;&nbsp; &nbsp;[Date Filters].[Date Filter Value].Children&nbsp;<br />} ON 1<br />FROM [Time Calc POC]</font></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/9795976_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Get a list of attribute values from a hierarchy.</font><br /><font size="1"><font color="#da8044">SELECT {} on 0,</font><br /><font color="#da8044">[Product].[Product Categories].[Product].Members on 1</font><br /></font><font color="#da8044"><font size="1">FROM [Adventure Works]</font></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/5931436_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Get a list of attributes including the SSRS parameter value.</font><br /><font size="1"><font color="#da8044">WITH&nbsp;</font><br /><font color="#da8044">MEMBER [Measures].[ParameterCaption] AS [Promotion].[Promotion Category].CURRENTMEMBER.MEMBER_CAPTION&nbsp;</font><br /><font color="#da8044">MEMBER [Measures].[ParameterValue] AS [Promotion].[Promotion Category].CURRENTMEMBER.UNIQUENAME</font><br /><font color="#da8044">SELECT {[Measures].[ParameterCaption], [Measures].[ParameterValue]} ON COLUMNS ,</font><br /><font color="#da8044">[Promotion].[Promotion Category].Children on ROWS</font><br /></font><font color="#da8044"><font size="1">FROM [Adventure Works]</font></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/8117894_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Include the <strong>All </strong>member</font><br /><font color="#da8044"><font size="1">WITH&nbsp;<br />MEMBER [Measures].[ParameterCaption] AS [Promotion].[Promotion Category].CURRENTMEMBER.MEMBER_CAPTION&nbsp;<br />MEMBER [Measures].[ParameterValue] AS [Promotion].[Promotion Category].CURRENTMEMBER.UNIQUENAME<br />SET [Promotion Category] AS [Promotion].[Promotion Category].ALLMEMBERS<br />SELECT {[Measures].[ParameterCaption], [Measures].[ParameterValue]} ON COLUMNS ,<br />[Promotion Category] on ROWS<br />FROM [Adventure Works]</font></font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/8751355_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">I hope this little blog post helps to get you started on extracting attribute values without using a related measure. &nbsp;Enjoy!</font></div>]]></content:encoded></item><item><title><![CDATA[SSAS DSV in dimension pane is empty or you receive error: ﻿Error HRESULT E_FAIL has been returned from a call to a COM component]]></title><link><![CDATA[https://www.delorabradish.com/ssas/ssas-dsv-in-dimension-pane-is-empty-or-you-receive-error-error-hresult-e_fail-has-been-returned-from-a-call-to-a-com-component]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/ssas-dsv-in-dimension-pane-is-empty-or-you-receive-error-error-hresult-e_fail-has-been-returned-from-a-call-to-a-com-component#comments]]></comments><pubDate>Mon, 02 Nov 2015 22:29:33 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/ssas-dsv-in-dimension-pane-is-empty-or-you-receive-error-error-hresult-e_fail-has-been-returned-from-a-call-to-a-com-component</guid><description><![CDATA[Issue: When you open a dimension (*.dim) file in a Visual Studio 2012 project, you either receive the following error, the dimension opens with a blank data source view (DSV) pane, or the dimension opens with no DSV pane at all. &nbsp;This is highly problematic when you need to add new attributes to the dimension.COM Error Example.&nbsp; Click &lt;OK&gt; and the dimension will open with either no DSV pane, or an empty DSV pane.         &#65279;Empty DSV pane example:         Internet Solution:&n [...] ]]></description><content:encoded><![CDATA[<div class="paragraph" style="text-align:left;"><font color="#c2743b"><strong>Issue:</strong></font><font color="#2a2a2a"> Wh<strong>e</strong>n you open a dimension (*.dim) file in a Visual Studio 2012 project, you either receive the following error, the dimension opens with a blank data source view (DSV) pane, or the dimension opens with no DSV pane at all. &nbsp;This is highly problematic when you need to add new attributes to the dimension.</font><br /><br /><font color="#c2743b"><strong>COM Error Example.&nbsp;</strong></font><font color="#2a2a2a"> Click &lt;OK&gt; and the dimension will open with either no DSV pane, or an empty DSV pane.</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/5700848.png?638" alt="Picture" style="width:638;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><span id="selectionBoundary_1446502933802_35953544289804995">&#65279;</span><strong><font color="#c2743b">Empty DSV pane example:</font></strong></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/1940851_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><strong><font color="#c2743b">Internet Solution:</font></strong><font color="#c2743b">&nbsp; </font><font color="#2a2a2a">You may have already read elsewhere on the Internet that this issue can be caused by the developer&rsquo;s <em>Control Panel --&gt; Clock, Language &amp; Region --&gt; Language</em> not being set to <strong>English (United States)</strong> and/or <em>Control Panel --&gt; Clock, Language &amp; Region --&gt;&nbsp;Region --&gt; Home Location</em> not being set to </font><strong><font color="#2a2a2a">United States</font></strong><font color="#2a2a2a">.&nbsp;</font><br /><br /><font color="#2a2a2a">As this behavior only manifested itself for us in two of twenty dimensions and our Language and Regions were already set to United States, we pursued other alternatives.&nbsp; There are two relatively simple fixes, providing your dimension sources from a single table.</font><br /><font size="3" color="#c2743b"><br /><strong>Alternative Solution #1 (preferred):</strong></font><ol><li><font color="#2a2a2a">Open a dimension in the solution that does show the Data Source View in the DSV pane.</font></li><li><font color="#2a2a2a">Right mouse click on your dimension name and choose <strong>View Code</strong>.</font></li><li><font color="#2a2a2a">Copy to clipboard every line starting from ...</font></li></ol></div>  <div><div class="wsite-multicol"><div class="wsite-multicol-table-wrap" style="margin:0 -15px;"> 	<table class="wsite-multicol-table"> 		<tbody class="wsite-multicol-tbody"> 			<tr class="wsite-multicol-tr"> 				<td class="wsite-multicol-col" style="width:12.048192771084%; padding:0 15px;"> 					 						  <div class="wsite-spacer" style="height:50px;"></div>   					 				</td>				<td class="wsite-multicol-col" style="width:87.951807228916%; padding:0 15px;"> 					 						  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/7443474_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>   					 				</td>			</tr> 		</tbody> 	</table> </div></div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;As show here --&gt;</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/5374932_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">&nbsp; &nbsp; 4. &nbsp; &nbsp; &nbsp;Now open the XML for the offending dimension and find the same section.&nbsp;</font><br /><font color="#2a2a2a">&nbsp; &nbsp; 5. &nbsp; &nbsp; &nbsp;Copy and paste the XML from the working dimension.</font><br /><font color="#2a2a2a">&nbsp; &nbsp; 6. &nbsp; &nbsp; &nbsp;Update the <strong>LogicalObject</strong> property which should contain the table name or named query used by the offending dimension.</font><br /><font color="#2a2a2a">&nbsp; &nbsp; 7. &nbsp; &nbsp; &nbsp;Save the dimension file to disc, then reopen it in Solution Explorer as usual.&nbsp; Your DSV pane should now contain the solution DSV object you specified in <strong>LogicalObject</strong>.</font><br /><font size="3"><br /><font color="#c2743b"><strong>Alternative Solution #2</strong></font></font><br /><font color="#2a2a2a">We also found a workable solution to be right mouse clicking in the empty dimension's DSV pane and selecting <strong>Show All Tables</strong>.&nbsp; This is not the preferred solution because if you have many tables in your solution&rsquo;s DSV, you have to wade through them all to find the one table you want for your dimension.&nbsp; This solution also did not work when the <strong>Error HRESULT E_FAIL has been returned from a call to a COM component</strong> error resulted in no DSV pane at all.<br /><br /><strong><font color="#c2743b">Side Note:</font></strong><font color="#2a2a2a">&nbsp; If this error is happening when you try to open the&nbsp;</font><u>solution&rsquo;s&nbsp;</u><font color="#2a2a2a">DSV, it can be caused by the DSV having been created in Visual Studio 2014 while the developer is trying to open the DSV in Visual Studio 2012.&nbsp; (You can read a very good MSDN blog post on how to fix this particular issue here --&gt;<br />&nbsp;</font><a href="http://blogs.msdn.com/b/sqlblog/archive/2015/06/10/ssas-dsv-com-error-that-breaks-ssdt-ssas-design-backward-compatibility.aspx" target="_blank">http://blogs.msdn.com/b/sqlblog/archive/2015/06/10/ssas-dsv-com-error-that-breaks-ssdt-ssas-design-backward-compatibility.aspx</a><span>.)</span></font></div>]]></content:encoded></item><item><title><![CDATA[SSAS Impact of Setting ErrorConfiguration - KeyDuplicate property to IgnoreError]]></title><link><![CDATA[https://www.delorabradish.com/ssas/impact-of-ignoring-errorconfiguration-keyduplicate]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/impact-of-ignoring-errorconfiguration-keyduplicate#comments]]></comments><pubDate>Mon, 02 Nov 2015 01:19:41 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/impact-of-ignoring-errorconfiguration-keyduplicate</guid><description><![CDATA[Having come from an OLTP background, I used to think that ignoring duplicate keys in a dimension resulted in duplicated fact records (measures) in a multidimensional cube.&nbsp; This, however, is not the case.&nbsp; Even if the primary key of the dimension is duplicated, SSAS is smart enough to not duplicate related fact rows. &nbsp;The POC explained in this blog post was originally created to prove the very opposite, but now I have learned a different version of the truth, and I thought this li [...] ]]></description><content:encoded><![CDATA[<div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Having come from an OLTP background, I used to think that ignoring duplicate keys in a dimension resulted in duplicated fact records (measures) in a multidimensional cube.&nbsp; This, however, is not the case.&nbsp; Even if the primary key of the dimension is duplicated, SSAS is smart enough to not duplicate related fact rows. &nbsp;</font><font color="#2a2a2a">The POC explained in this blog post was originally created to prove the very opposite, but now I have learned a different version of the truth, and I thought this little POC might interest someone else.&nbsp; So, let&rsquo;s get started:</font><br /><font color="#2a2a2a">&nbsp;</font><br /><font color="#2a2a2a">First, just because we can get away with something, is not a good reason to do it.&nbsp; In other words, even though SSAS lets us have duplicate primary dimension keys, and what SSAS&nbsp;considers&nbsp;duplicate values in columns, is not an excuse to allow&nbsp;them.&nbsp; </font><font color="#a85f2e"><strong>Data integrity should be considered non-negotiable.</strong></font><br /><font color="#2a2a2a">&nbsp;</font><br /><font color="#2a2a2a">Second, the dimension property I am talking about can be found in any dimension under </font><font color="#a85f2e">[Dimension Name] --&gt; Properties --&gt; ErrorConfiguration --&gt; KeyDuplicate.</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/5147420_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">99.9% of the time, the correct selection for the </font><font color="#a85f2e">KeyDuplicate</font><font color="#2a2a2a"> property is </font><font color="#a85f2e">ReportAndStop</font><font color="#2a2a2a">.&nbsp; I strongly suggest that each of us just decide to set it now and work through the data cleansing issues that this error handling <em>will almost assuredly expose</em>. &nbsp; Specifically, the&nbsp;</font><font color="#2a2a2a">error that SSAS generates is as follows: &nbsp;</font></div>  <div class="paragraph" style="text-align:center;"><em><font color="#a85f2e">Dimension Processing Error: Errors in the OLAP storage engine: A duplicate attribute key has been found when processing: Table: 'Dimension Name', Column: 'Column Name', Value: 'abc123&rsquo;. The attribute is 'Attribute Name'.</font></em></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Third, let us be clear, &ldquo;duplicate key&rdquo; does not just mean &ldquo;duplicate primary key&rdquo;.&nbsp; What Analysis Services is talking about is the </font><strong><font color="#a85f2e">KeyColumns</font></strong><font color="#2a2a2a"> property associated with each attribute within a dimension. &nbsp;In the screen print below, the key of the Product <em>attribute</em> is the ProductKey <em>column</em> from the Product<em> table</em>. &nbsp;This happens to also be the primary key of both the table and the dimension.</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:10px;padding-bottom:10px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/7305016.png?396" alt="Picture" style="width:396;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">However, every attribute in a dimension has a KeyColumns property and for most attributes, the KeyColumns value is the column itself. &nbsp;If the attribute is used in a hierarchy, you will often find that the KeyColumns property is a composite key containing greater than one column from the source table. &nbsp;In the screen print below, the key of the </font><font color="#a85f2e">Calendar Quarter</font><em style="color: rgb(42, 42, 42);"> attribute </em><font color="#2a2a2a">is the&nbsp;composite&nbsp;column values of </font><font color="#a85f2e">CalendarYear</font><font color="#2a2a2a"> and </font><font color="#a85f2e">CalendarQuarter</font> <em style="color: rgb(42, 42, 42);">columns</em><font color="#2a2a2a"> from the </font><font color="#a85f2e">Date </font><em style="color: rgb(42, 42, 42);">table</em><font color="#2a2a2a">.</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/7706615_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Now, let&rsquo;s mock up a little data and see what really happens if we set the </font><font color="#a85f2e">ErrorConfiguration:KeyDuplicate</font><font color="#2a2a2a"> property to</font><font color="#a85f2e">&nbsp;</font><span><font color="#a85f2e">IgnoreError</font> </span><font color="#2a2a2a">instead of </font><font color="#a85f2e">ReportAndStop</font><font color="#2a2a2a">. &nbsp;The DSV tables I created are pictured here:</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/4925391_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">For the Fact table&hellip;.</font><br /><font size="2"><font color="#a85f2e">SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 AS PK, 100 AS NetSales, 1 AS DimFK</font><br /><font color="#a85f2e">UNION</font></font><br /><font color="#a85f2e"><font size="2">SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 AS PK, 999 AS NetSales, 2 AS DimFK</font></font><br /><font color="#a85f2e">&nbsp;</font><br /><font color="#2a2a2a">For the DuplicateStringsDIM &hellip;</font><br /><font size="2"><font color="#a85f2e">SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 AS PK, 'CODE 1' AS Code, 'Descr 1' AS Description, LEN('Descr 1') AS DescrLen</font><br /><font color="#a85f2e">UNION</font><br /><font color="#a85f2e">SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 AS PK, 'Code 1' AS Expr1, 'Descr 1' + CHAR(9) AS Expr2, LEN('Descr 1' + CHAR(9))</font><br /><font color="#a85f2e">UNION</font></font><br /><font color="#a85f2e"><font size="2">SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 AS PK, 'Code 3' AS Expr1, 'Descr 3' AS Expr2, LEN('Descr 3')</font></font><br /><font color="#a85f2e">&nbsp;</font><br /><font color="#2a2a2a">For the DuplicatePKsDIM&hellip;.</font><br /><font size="2"><font color="#a85f2e">SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 AS PK, 'Code 1' AS Code, 'Descr 1' AS Description</font><br /><font color="#a85f2e">UNION</font><br /><font color="#a85f2e">SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 AS PK, 'Code 2' AS Expr1, 'Descr 2' AS Expr2</font><br /><font color="#a85f2e">UNION</font></font><br /><font color="#a85f2e"><font size="2">SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 AS PK, 'Code 3' AS Expr1, 'Descr 3' AS Expr2</font></font><br />&nbsp;<br /><font color="#2a2a2a">I then created two dimensions &ndash; nothing fancy, just regular old dimensions with no hierarchies.&nbsp;&nbsp;</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/2150481_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Each dimension has </font><font color="#a85f2e">ErrorConfiguration:KeyDuplicate</font><font color="#2a2a2a"> set to</font><font color="#a85f2e"> IgnoreError</font><font color="#2a2a2a">.</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/4192151_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Next, I built a simple cube, and processed the cube.</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/4948906_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/9026576_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">&#8203;While the cube was taking 5 seconds to process full, I jumped over to SSMS (SQL Server Management Studio) and wrote a little t-SQL.</font><br /><font color="#2a2a2a">&nbsp;</font><br /><font size="2" color="#a85f2e">--Create the table to hold duplicate code values<br />insert @DuplicateStringsDIM<br />SELECT *<br />FROM (<br />SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 AS PK, 'Code 1' AS Code, 'Descr 1' AS Description<br />UNION<br />SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 AS PK, 'CODE 1' AS Expr1, 'Descr 1' + CHAR(9) AS Expr2<br />UNION<br />SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 AS PK, 'Code 3' AS Expr1, 'Descr 3' AS Expr2<br />) x<br />&nbsp;<br />&nbsp;--Create the table to hold duplicate primary key values<br />DECLARE @DuplicatePKsDIM TABLE (dPK int, Code varchar(30), Descr varchar(60))<br />insert @DuplicatePKsDIM<br />SELECT *<br />FROM (<br />SELECT&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1 AS PK, 'Code 1' AS Code, 'Descr 1' AS Description<br />UNION<br />SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 AS PK, 'Code 2' AS Expr1, 'Descr 2' AS Expr2<br />UNION<br />SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 AS PK, 'Code 3' AS Expr1, 'Descr 3' AS Expr2<br />) x<br />&nbsp;<br />&nbsp;--create the table to hold the measures<br />DECLARE @FactTbl TABLE (fPK int, NetSales int, DimFK int)<br />insert @FactTbl<br />SELECT *<br />FROM (<br />SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 AS PK, 100 AS NetSales, 1 AS DimFK<br />UNION<br />SELECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 AS PK, 999 AS NetSales, 2 AS DimFK<br />) x<br />&nbsp;<br />--the results are as expected<br />--the fact record is duplicated for each duplicate DIM PK<br />SELECT *<br />from @FactTbl f<br />LEFT JOIN @DuplicatePKsDIM d1 on f.DimFK = d1.dPK</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/2825060_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font size="2" color="#a85f2e">--the results are as expected:<br />--the 2nd 'Descr 1' value has a special character, and therefore groups into two separate rows<br />SELECT d2.Descr, SUM(NetSales) as SumOfNetSales<br />from @FactTbl f<br />LEFT JOIN @DuplicateStringsDIM d2 on f.DimFK = d2.dPK<br />GROUP BY d2.Descr</font><br /></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/2167258_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">The above results in t-SQL makes sense</font><ol><li><font color="#2a2a2a">We had a duplicate primary key in the @DuplicatePKsDIM, so we doubled our</font><font color="#a85f2e"> NetSales </font><font color="#2a2a2a">amount.</font></li><li><font color="#2a2a2a">We had a hidden special character lurking in a string column in the @DuplicateStringDIM, so we ended up with two code values, </font><font color="#a85f2e">Code 1</font><font color="#2a2a2a">, that look duplicated.</font></li></ol><br /><font color="#2a2a2a">Now let&rsquo;s browse the cube whose data source view contained the exact same rows. &nbsp;</font><font color="#2a2a2a">First, test the measure all by itself.&nbsp; All is well.</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/7923359_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Now look what happens when we slice by PK.</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/6902363_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">The reality is that there are two PKs with a value of #1 in the DSV, but SSAS has not duplicated the measure amount.&nbsp; We still have just 100 net sales for dimension PK #1.&nbsp; Furthermore, we have lost &lsquo;Code 2&rsquo; and &lsquo;Descr 2&rsquo;, why?&nbsp; <u>Analysis services has taken the row values of the first instance of the PK, and has ignored the second.</u><br />&nbsp;<br />This&nbsp;phenomena&nbsp;has nothing to do with the measure group. &nbsp;The following MDX query shows what is actually in the [Duplicate PKs&nbsp;DIM] -- two rows and not three.</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/8273100_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Don&rsquo;t forget what was really in our data source table, @DuplicatePKsDim:</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/3831456_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Now let&rsquo;s look at what SSAS considers a &ldquo;duplicate&rdquo; in the [DuplicateStringsDIM] dimension.</font></div>  <div><div class="wsite-image wsite-image-border-medium " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/8566164_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">If </font><font color="#a85f2e">ErrorConfiguration:KeyDuplicate</font><font color="#2a2a2a"> is set to </font><font color="#a85f2e">ReportAndStop...</font><ul><li><font color="#2a2a2a">Primary Key #1 will result in a&nbsp;duplicate&nbsp;key error because SSAS knows this is the PK and there are two identical values.<br /></font></li><li><font color="#2a2a2a">[Code 1] will result in a duplicate key error because of the case difference.&nbsp; <br /></font></li><li><font color="#2a2a2a">[Descr 1] will result in a duplicate key error because of the hidden special character.</font></li></ul><font color="#2a2a2a">However, in our POC, w</font><font color="#2a2a2a">e have </font><font color="#a85f2e">IgnoreError</font><font color="#2a2a2a"> selected, so again, SSAS has taken the first instance of the</font> <font color="#a85f2e">KeyColumn</font><br /> <font color="#2a2a2a">attribute.</font><ul><li><font color="#2a2a2a">The [Duplicate PKs DIM] only has one instance of primary key values #1</font></li><li><font color="#2a2a2a">The [Duplicate Strings DIM] has the first instance of [Code 1] and the first instance of [Descr 1]</font></li></ul><font color="#2a2a2a">When we slice by the primary key, our Net Sales is not duplicated.</font><br /></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:left"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/6544770_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#a85f2e">&nbsp;</font><strong><font color="#a85f2e">In summary, </font></strong><ol><li><font color="#2a2a2a">Duplicate primary keys, collation differences or special characters will not duplicate related measures.</font></li><li><font color="#2a2a2a">This is not a good reason to allow unclean data into the data sources of the data source view tables or named queries.</font></li><li><font color="#2a2a2a">However, if you cannot control the ETL data cleansing process, but must control daily cube processing success, ignoring duplicate key errors might be something you consider as a last resort.</font></li><li><font color="#2a2a2a">Understand that Analysis Services will select the &ldquo;first instance&rdquo; of a duplicate key, so you might not get the row / attribute values of preference.</font></li></ol><br /></div>]]></content:encoded></item><item><title><![CDATA[Excel Error: The item could not be found in the OLAP cube﻿]]></title><link><![CDATA[https://www.delorabradish.com/ssas/excel-error-the-item-could-not-be-found-in-the-olap-cube]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/excel-error-the-item-could-not-be-found-in-the-olap-cube#comments]]></comments><pubDate>Sun, 01 Nov 2015 14:41:27 GMT</pubDate><category><![CDATA[Excel]]></category><category><![CDATA[SSAS]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/excel-error-the-item-could-not-be-found-in-the-olap-cube</guid><description><![CDATA[Issue: When working in Excel 2013 Prof Ed and a SQL Server 2012 multidimensional cube, you receive the following error when adding a&nbsp;hierarchy&nbsp;or attribute to the FILTERS section of the PivotTable Fields GUI.         The above error is usually caused by an object that was removed or renamed in the cube. &nbsp;However, this was not the case for a&nbsp;recent&nbsp;client. &nbsp;I Googled the error (like you probably did to even arrive at my blog site), but found nothing except&nbsp;that  [...] ]]></description><content:encoded><![CDATA[<div class="paragraph" style="text-align:left;"><strong><font color="#a85f2e">Issue:</font></strong> <font color="#2a2a2a">When working in Excel 2013 Prof Ed and a SQL Server 2012 multidimensional cube, you receive the following error when adding a&nbsp;hierarchy&nbsp;or attribute to the FILTERS section of the PivotTable Fields GUI.</font></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:0px;padding-bottom:0px;margin-left:0px;margin-right:0px;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/5411974_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><font color="#2a2a2a">The above error is usually caused by an object that was removed or renamed in the cube. &nbsp;However, this was not the case for a&nbsp;recent&nbsp;client. &nbsp;I Googled the error (like you probably did to even arrive at my blog site), but found nothing except&nbsp;that an object was deleted or removed from the cube. &nbsp;As this was not our scenario, I'm doing this little write-up hoping that is will be helpful to someone in the same&nbsp;predicament.</font><br /><br /><strong><font color="#a85f2e">Summary Solution:&nbsp;</font></strong><ol><li><font color="#2a2a2a">Remove the offending dimension from the multidimensional cube</font></li><li><font color="#2a2a2a">Save your Visual Studio solution</font></li><li><font color="#2a2a2a">Rebuilt your Visual Studio solution.</font></li><li><font color="#2a2a2a">Add the dimension back into your multidimensional cube.</font></li><li><font color="#2a2a2a">Deploy and reprocess the cube.</font></li><li><font color="#2a2a2a">Test both the hierarchy and a couple of independent attributes in Excel's PivotTable Fields &lt;FILTERS&gt; section.</font></li></ol><br /><strong><font color="#a85f2e">Cause of the Error:</font></strong><span>&nbsp;</span><font color="#2a2a2a">Unknown. &nbsp;I have found on more than on one occasion that the underlying XML of multidimensional cubes becomes "out of sync". &nbsp;I realize this isn't a very technical response, but if you have spent time comparing "working" XML code to "unworking" code, you know that sometimes it is easier to just remove and readd the object.</font><br /><br /><strong><font color="#a85f2e">Resolution Logic:</font> </strong><font color="#2a2a2a">&nbsp;In the latest &nbsp;occurrence&nbsp;of this error, I worked through the following steps trying to find the cause before throwing in the towel and removing the dimension from the cube. &nbsp;It was determined that ..</font><ul><li><font color="#2a2a2a">This error only&nbsp;occurred&nbsp;with <u>one of two</u> role playing dimensions. &nbsp;15+ other dimensions in the cube did not produce the error.</font></li><li><font color="#2a2a2a">This behavior happened&nbsp;with both hierarchies and independent attributes.</font></li><li><font color="#2a2a2a">This error only occurred in Excel's FILTERS section of PivotTable Fields. &nbsp;There was no problem filtering through COLUMNS or ROWS.</font></li><li><font color="#2a2a2a">This behavior did not happen in a SSMS (SQL Server Management Studio) cube browser. &nbsp; Both hierarchies and attributes filtered just fine.</font></li><li><font color="#2a2a2a">This error was&nbsp;not measure group specific &ndash; it occurred with no measure group selected (i.e. no measures dropped into&nbsp;VALUES).</font></li></ul><font color="#2a2a2a">(And now I began looking for property differences that might cause this error...)</font><ul><li><font color="#2a2a2a">The role playing DIM that did work properly, had even a longer name than the non-functioning role playing DIM.</font></li><li><font color="#2a2a2a">The role playing DIM that did work used an alias name. &nbsp;The non-functioning role playing DIM did not.</font></li><li><font color="#2a2a2a">The role&nbsp;playing DIM that did work had <strong>HierarchyUniqueNameStyl</strong>e set to the default value of <strong>IncludeDimensionName</strong>. &nbsp;The non-functioning role playing DIM had the default value of <strong>ExcludeDimensionName</strong>. &nbsp;I found a 2nd DIM that also was set to <strong>ExcludeDimensionName</strong>, and it worked just fine in Excel's FILTERS section.</font></li></ul><strong><font color="#a85f2e">Conclusion:</font></strong><br /><font color="#2a2a2a">It was a bit of work to remove a shared dimension from a large cube and re-add it, checking to make sure all cube relationships and properties remained the same, but in the end, this is what fixed the error. &nbsp;if you have come across this same problem and have found a better solution, please post it in blog comments. &nbsp;I'd like to hear your creative solution!</font></div>]]></content:encoded></item><item><title><![CDATA[Time Calculations: Returning NULL Values for Future Days]]></title><link><![CDATA[https://www.delorabradish.com/ssas/time-calculations-returning-null-values-for-future-days]]></link><comments><![CDATA[https://www.delorabradish.com/ssas/time-calculations-returning-null-values-for-future-days#comments]]></comments><pubDate>Mon, 27 Jul 2015 22:40:14 GMT</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">https://www.delorabradish.com/ssas/time-calculations-returning-null-values-for-future-days</guid><description><![CDATA[Sometimes users do not want to see time calculations for days in the future -- even if there is data. &nbsp;To &ldquo;nullify&rdquo; date calculation for days in the future, follow these steps:    1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Create an IsFutureDate named calculation in your date dimension.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CASE WHEN FullDateAlternateKey &gt; GetDate() THEN 1 ELSE 0 END         2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add the new attribute to your date dimensio [...] ]]></description><content:encoded><![CDATA[<div class="paragraph" style="text-align:left;"><font color="#2a2a2a">Sometimes users do not want to see time calculations for days in the future -- even if there is data. &nbsp;To &ldquo;nullify&rdquo; date calculation for days in the future, follow these steps:<br /><span style=""></span><br /><span style=""></span>    1.<span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Create an IsFutureDate named calculation in your date dimension.<br /><span "color:#365f91;mso-themecolor:="" accent1;mso-themeshade:191"="" style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CASE WHEN FullDateAlternateKey &gt; GetDate() THEN 1 ELSE 0 END</span></font><br /><span style=""></span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/4365409_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>  <div class="paragraph" style="text-align:left;"><span style="color: rgb(42, 42, 42);">2.</span><span style="color: rgb(42, 42, 42);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(42, 42, 42);">Add the new attribute to your date dimension.</span><br /><font color="#2a2a2a"><span style=""></span></font><br /><font color="#2a2a2a"><span style=""></span></font><span style="color: rgb(42, 42, 42);">3.</span><span style="color: rgb(42, 42, 42);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(42, 42, 42);">Add the following script to the end of your MDX time calculations.</span><br /><font color="#2a2a2a"><span style=""></span></font><br /><span style=""></span><span style=""></span><font color="#da8044">--set future date calculations to NULL<span style=""></span><br /><span style=""></span><br /><span style=""></span><span style=""></span>SCOPE&nbsp;([Date Default].[Is Future Date].&amp;[1],<br /><span style=""></span><br /><span style=""></span><span style=""></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Date Ship].[Is Future Date].&amp;[1],<br /><span style=""></span><br /><span style=""></span><span style=""></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Date Due].[Is Future Date].&amp;[1]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style=""></span><br /><span style=""></span><span style=""></span>&nbsp;&nbsp;&nbsp; [Date Calculations].[Date Calculation Name].[YTD] =&nbsp;NULL;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style=""></span><br /><span style=""></span><span style=""></span>&nbsp;&nbsp;&nbsp; [Date Calculations].[Date Calculation Name].[YTD Change] =&nbsp;NULL;&nbsp;<br /><span style=""></span><br /><span style=""></span><span style=""></span>&nbsp;&nbsp;&nbsp; [Date Calculations].[Date Calculation Name].[YTD % Change] =&nbsp;NULL;<br /><span style=""></span><br /><span style=""></span><span style=""></span>&nbsp;&nbsp;&nbsp; [Date Calculations].[Date Calculation Name].[YTD Prior Year] =&nbsp;NULL;<br /><span style=""></span><br /><span style=""></span><span style=""></span>&nbsp;&nbsp;&nbsp; [Date Calculations].[Date Calculation Name].[MTD] =&nbsp;NULL;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style=""></span><br /><span style=""></span><span style=""></span>&nbsp;&nbsp;&nbsp;&nbsp;//add additional time calculations here as needed<span style=""></span><br /><span style=""></span><br /><span style=""></span><span style=""></span>END&nbsp;SCOPE;</font><font color="#2a2a2a"><span "font-size:9.0pt;font-family:consolas;="" color:#1e1e1e"="" style=""></span></font><br /><font color="#2a2a2a"><span style=""></span></font><br /><font color="#2a2a2a"><span style=""></span></font><span style="color: rgb(42, 42, 42);">4.</span><span style="color: rgb(42, 42, 42);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=""><font color="#2a2a2a">Verify the results.&nbsp; In the screen print below, the current date was 7/24/2015.&nbsp; All future days returned empty cell values.</font></span></div>  <div><div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center"> <a> <img src="https://www.delorabradish.com/uploads/5/3/4/3/53431729/3536038_orig.png" alt="Picture" style="width:auto;max-width:100%" /> </a> <div style="display:block;font-size:90%"></div> </div></div>]]></content:encoded></item></channel></rss>