<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'SSRS', 'MDX', and 'SSAS'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=SSRS,MDX,SSAS&amp;orTags=0</link><description>Search results matching tags 'SSRS', 'MDX', and 'SSAS'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>PASS Summit 2010: Epilogue</title><link>http://sqlblog.com/blogs/stacia_misner/archive/2010/11/15/30605.aspx</link><pubDate>Mon, 15 Nov 2010 21:16:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:30605</guid><dc:creator>smisner</dc:creator><description>&lt;p style="margin:0in 0in 10pt;"&gt;Another &lt;a target="_blank" href="http://www.sqlpass.org/summit/na2010/"&gt;PASS Summit&lt;/a&gt; has come and gone, and a good time was had by all. The song at the &lt;a target="_blank" href="http://www.sqlpass.org/summit/na2010/LiveKeynotes/Tuesday.aspx"&gt;opening keynote&lt;/a&gt; sums up the experience quite nicely, "Simply the Best." My favorite quote of the week comes from Andy Leonard (&lt;a target="_blank" href="http://sqlblog.com/blogs/andy_leonard"&gt;blog&lt;/a&gt;| &lt;a target="_blank" href="http://twitter.com/AndyLeonard"&gt;twitter&lt;/a&gt;) who tweeted on November 9, "&lt;a title="#sqlpass" href="http://twitter.com/#!/search?q=#sqlpass"&gt;#sqlpass&lt;/a&gt; is a family reunion. :{&amp;gt;" Oddly enough, Andy is one of the few people that I DIDN'T get to see last week, but not for lack of trying. Sorry, Andy!&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;As an independent consultant, I don't get to interact regularly with my peers, so I love the reunion aspect of PASS. And now that I've started following people on Twitter, my universe of colleagues has expanded even more, and I was delighted to meet the people behind the avatars.&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;The joy of PASS is not limited to those of us who have attended for many years. As I was sitting in the airport last Friday, I recognized an attendee who was a first-timer and asked about his experience. He replied that it exceeded expectations. He was so anxious to get back to work to put what he learned into practice. He felt that the value of the knowledge that he is bringing back to the office from PASS was so much greater than the price of the conference. Now that's a ringing endorsement if I ever heard one.&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;There is so much more that could be said about PASS, and many in the community have already posted their thoughts on Twitter and on their blogs. There has been quite a stir in the business intelligence community this past week about the future of Analysis Services, about which I will comment in a future post. Today, however, I will focus on a few follow-up comments and links to resources related to activities in which I participated last week.&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;&lt;b&gt;Getting Started In Blogging And Technical Speaking&lt;/b&gt;&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;Kendal Van Dyke (&lt;a target="_blank" href="http://kendalvandyke.blogspot.com/"&gt;blog&lt;/a&gt;| &lt;a target="_blank" href="http://twitter.com/SQLDBA"&gt;twitter&lt;/a&gt;) presented a session with tips for getting started in either of blogging or speaking. He invited a panel of experts to join him, including myself, Rob Farley (not pictured below) (&lt;a target="_blank" href="http://sqlblog.com/blogs/rob_farley"&gt;blog&lt;/a&gt;| &lt;a target="_blank" href="http://twitter.com/rob_farley"&gt;twitter&lt;/a&gt;), Aaron Bertrand (&lt;a target="_blank" href="http://sqlblog.com/blogs/aaron_bertrand"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/AaronBertrand"&gt;twitter&lt;/a&gt;), Buck Woody (&lt;a target="_blank" href="http://buckwoody.com/"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/buckwoody"&gt;twitter&lt;/a&gt;), Todd McDermid (&lt;a target="_blank" href="http://toddmcdermid.blogspot.com/"&gt;blog&lt;/a&gt;| &lt;a target="_blank" href="http://twitter.com/Todd_McDermid"&gt;twitter&lt;/a&gt;), Mike Walsh (&lt;a target="_blank" href="http://www.straightpathsql.com/blog"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/mike_walsh"&gt;twitter&lt;/a&gt;), Thomas LaRock (&lt;a target="_blank" href="http://thomaslarock.com/backstage/"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/SQLRockstar"&gt;twitter&lt;/a&gt;), Ted Krueger (&lt;a target="_blank" href="http://www.lessthandot.com/"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/onpnt"&gt;twitter&lt;/a&gt;), Patrick LeBlanc (&lt;a target="_blank" href="http://sqldownsouth.blogspot.com/"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/patrickdba"&gt;twitter&lt;/a&gt;), Andy Warren (&lt;a target="_blank" href="http://www.sqlservercentral.com/blogs/andy_warren/default.aspx"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/sqlandy"&gt;twitter&lt;/a&gt;), and Brent Ozar (&lt;a target="_blank" href="http://www.brentozar.com/"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/BrentO"&gt;twitter&lt;/a&gt;).&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.datainspirations.com/wp-content/uploads/2010/11/5168176314_fe721e07b7.jpg"&gt;&lt;img class="size-full wp-image-285" title="Kendal Van Dyk's session at PASS Summit 2010" alt="" width="500" height="375" src="http://blog.datainspirations.com/wp-content/uploads/2010/11/5168176314_fe721e07b7.jpg"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;(Photo courtesy of Brent Ozar)&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;Who had control of this very interactive session? You'll have to &lt;a target="_blank" href="http://www.sqlpass.org/summit/na2010/Home/OnSiteFAQ/DVDs.aspx"&gt;buy the PASS Summit DVD&lt;/a&gt; to find out!&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;I waited patiently for my turn to speak. With a room full of speakers, getting your own turn can be a challenge! I heard a few attendees express concern that they didn't know what to write about, or that someone else has covered the topic. My response to this concern is that everyone has a unique take on a topic, and that's why T-SQL Tuesday is such a great way both to learn and to contribute. T-SQL Tuesday was started by Adam Mechanic (&lt;a target="_blank" href="http://sqlblog.com/blogs/adam_machanic"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/AdamMachanic"&gt;twitter&lt;/a&gt;) and gives everyone with an opinion (and who doesn't have one?) or a specific experience to add to the topic. You can &lt;a target="_blank" href="http://sqlblog.com/blogs/adam_machanic/archive/2009/11/30/invitation-to-participate-in-t-sql-tuesday-001-date-time-tricks.aspx"&gt;see the first invitation to T-SQL Tuesday here&lt;/a&gt; to see how it all started and &lt;a target="_blank" href="http://www.sqlskills.com/BLOGS/PAUL/category/T-SQL-Tuesday.aspx"&gt;the most recent T-SQL Tuesday posts&lt;/a&gt; hosted by Paul Randal (&lt;a target="_blank" href="http://sqlskills.com/blogs/paul/"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/paulrandal"&gt;twitter&lt;/a&gt;). The best way to keep tabs on who's hosting the next round is to follow the #TSQL2sDay hash tag on Twitter.&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;Unfortunately, I didn't get to hang out for the entire presentation, because I had to move on to the…&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;&lt;b&gt;Women in Technology Panel&lt;/b&gt;&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;I was honored to participate as a panelist for this year's Women in Technology luncheon. It was well attended, and I heard so many positive comments after the event from both men and women. I drew inspiration from my fellow panelists as well as the stories shared with me by other women attending PASS this year. You can view a recording of the event &lt;a target="_blank" href="http://www.sqlpass.org/summit/na2010/LiveKeynotes/WITLuncheon.aspx"&gt;here&lt;/a&gt; if you're a registered member of PASS (which is free to join).&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;It's so difficult to say what the right answer is for increasing the numbers of women in technology. The numbers are diminishing at a deplorable rate (&lt;a target="_blank" href="http://blog.datainspirations.com/2010/07/29/maybe-its-just-me-a-perspective-from-one-woman-in-it/"&gt;as I discussed in a previous post&lt;/a&gt;). It seems to me that to foster change we need to start laying the groundwork with our children. By "our children", I mean society in general, not me specifically, although I have tried do my part! On the one hand, I don't recommend forcing children into a career path that they can't embrace enthusiastically. On the other hand, I believe that one reason that girls don't pursue technology as an option is lack of exposure to the possibilities. Lynn Langit (&lt;a target="_blank" href="http://blogs.msdn.com/SoCalDevGal"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://www.twitter.com/llangit"&gt;twitter&lt;/a&gt;) is a role model for showing kids (not just girls!) how to explore these possibilities through &lt;a href="http://www.teachingkidsprogramming.org/"&gt;www.teachingkidsprogramming.org&lt;/a&gt;. Check it out! &lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;Along these lines, I proposed that maybe - as great a community as PASS is - we should collectively think about what we can do for our kids. Someone tweeted that I suggested we should bring our daughters to SQLSaturday, but actually I wondered aloud if we could do something &lt;i&gt;similar&lt;/i&gt; to SQLSaturday that focused on the kids (and not just girls). Maybe we could get some sponsors to help, too?&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;&lt;b&gt;Demystifying MDX in Reporting Services&lt;/b&gt;&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;In this session, I explained some of the nuances of working with MDX in Reporting Services. I have posted my demo reports &lt;a target="_blank" href="http://blog.datainspirations.com/uploads/DemystifingMDXinSSRS.zip"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;In addition, you might want to refer back to some of my recent posts about using dynamic MDX in Reporting Services: &lt;a target="_blank" href="http://blog.datainspirations.com/2010/10/07/using-dynamic-mdx-in-reporting-services-part-1/"&gt;Part 1&lt;/a&gt; and &lt;a target="_blank" href="http://blog.datainspirations.com/2010/10/09/using-dynamic-mdx-in-reporting-services-part-2/"&gt;Part 2&lt;/a&gt;.&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;If you're not familiar with MDX, I presented &lt;a target="_blank" href="http://www.sqlpass.org/LearningCenter/24HoursFall.aspx"&gt;Session 07: Intro to MDX&lt;/a&gt; for &lt;a target="_blank" href="http://www.sqlpass.org/24hours/fall2010/"&gt;24 Hours of Pass: Summit Preview&lt;/a&gt; which you can view if you have a free PASS membership. MDX is not going away any time soon, contrary to recent rumors, so invest some time learning it if you plan to work with real Analysis Services cubes, which will continue to have their place in the BI stack for several years to come.&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;&lt;b&gt;Real World Analysis Services Stored Procedures&lt;/b&gt;&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;This topic drew a larger audience than I expected as it's a fairly specialized topic. For years, I never needed to use Analysis Services Stored Procedures (ASSP), avoiding it because folklore said so due to performance hits. However, some things just can't be done any other way and I ran into such things this past year. To date, I haven't found much written about ASSP other than &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms176113.aspx"&gt;BOL&lt;/a&gt;, but you can find some &lt;a target="_blank" href="http://www.codeplex.com/ASStoredProcedures"&gt;excellent examples to download&lt;/a&gt; at CodePlex. Plus I've uploaded the &lt;a target="_blank" href="http://blog.datainspirations.com/uploads/ASSP.zip"&gt;very simple (non-production-ready) C# example&lt;/a&gt; that I used in my session demonstration for you to peruse.&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;&lt;b&gt;What's Next?&lt;/b&gt;&lt;/p&gt;&lt;p style="margin:0in 0in 10pt;"&gt;So now that I've completed all the training and Webcasts and conference sessions that I've been focused on the last couple of months (with one exception - &lt;a target="_blank" href="https://www2.gotomeeting.com/register/350482474"&gt;Delivering Information with Reporting Services&lt;/a&gt;, a free Webcast at 12 pm Pacific on Wednesday, November 17), I plan to get back to a more regular blogging schedule. There are certainly plenty of topics on my "to do" list!&lt;/p&gt;</description></item><item><title>Using Dynamic MDX in Reporting Services: Part 2</title><link>http://sqlblog.com/blogs/stacia_misner/archive/2010/10/08/29249.aspx</link><pubDate>Sat, 09 Oct 2010 01:31:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:29249</guid><dc:creator>smisner</dc:creator><description>&lt;P&gt;In this post, I continue my exploration of approaches to working with dynamic MDX in a Reporting Services dataset when you are using Analysis Services as a data source. I began this series with a look at &lt;A href="http://blog.datainspirations.com/2010/10/07/using-dynamic-mdx-in-reporting-services-part-1/" target="_blank"&gt;string conversion functions in Part 1&lt;/A&gt;. In Part 1, the dynamic MDX relied on parameters that work as a filter on the query results.&lt;/P&gt;

&lt;P&gt;But what if you want to change the structure of the query itself? A parameter won't help with that. Instead, you need to create the query string at run-time. However, the Analysis Services data source in Reporting Services doesn't allow you to use an expression to define the query string. That's okay- I'll just do an end run around that problem. I'll use an OLE DB provider to connect to my cube and then I can build up the query string by using an expression. In this post, I walk you through the process.&lt;/P&gt;

&lt;P&gt;The context for this demonstration is a report that allows the user to specify the sets that appear on rows and columns of a matrix and to select one measure. It's a very simple example that focuses on the dataset construction, and doesn't spend as much time on the beautification of the report. Hopefully, it will give you some ideas to leverage for your own reports.&lt;/P&gt;

&lt;P&gt;&lt;B&gt;Create a data source&lt;/B&gt;&lt;/P&gt;

&lt;P&gt;First, I need to create an OLE DB source. In the Type drop-down list, I select "OLE DB" and then I provide a connection string like this:&lt;/P&gt;

&lt;PRE&gt;Provider=MSOLAP.4;Data Source=.;Initial Catalog="Adventure Works DW 2008R2"&lt;/PRE&gt;
&lt;P&gt;The Edit button allows you to use a UI to generate the string if you don't want to remember how to construct it manually.&lt;/P&gt;

&lt;P&gt;﻿ &lt;A href="http://blog.datainspirations.com/wp-content/uploads/2010/10/OLEDBDataSource.png"&gt;&lt;IMG class="alignnone size-full wp-image-247" title="OLE DB Data Source" alt="" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/OLEDBDataSource.png" width="530" height="386"&gt;&lt;/A&gt;&lt;/P&gt;

&lt;P&gt;&lt;B&gt;Parameters&lt;/B&gt;&lt;/P&gt;

&lt;P&gt;This set of steps is necessary to create the lists from which the user makes the selection. In my very simple example, I have created two parameters - Rows and Columns - and hard-coded possible lists. You can do more interesting things here, of course. Just make sure that the user can't make the same selection for both parameters - whether you enforce that by manually providing the values or by doing something clever with a dynamically generated list based on a query.&lt;/P&gt;

&lt;P&gt;I created the Measure parameter with the following values:&lt;/P&gt;

&lt;TABLE cellSpacing="0" cellPadding="0"&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;B&gt;Label&lt;/B&gt;&lt;/TD&gt;

&lt;TD&gt;&lt;B&gt;Value&lt;/B&gt;&lt;/TD&gt;
&lt;/TR&gt;

&lt;TR&gt;
&lt;TD&gt;Sales Amount&lt;/TD&gt;

&lt;TD&gt;="[Measures].[Sales Amount]"&lt;/TD&gt;
&lt;/TR&gt;

&lt;TR&gt;
&lt;TD&gt;Order Quantity&lt;/TD&gt;

&lt;TD&gt;="[Measures].[Order Quantity]"&lt;/TD&gt;
&lt;/TR&gt;

&lt;TR&gt;
&lt;TD&gt;Gross Profit Margin&lt;/TD&gt;

&lt;TD&gt;="[Measures].[Gross Profit Margin]"&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TABLE&gt;

&lt;P&gt;I created the Columns parameters like this:&lt;/P&gt;

&lt;TABLE cellSpacing="0" cellPadding="0"&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;B&gt;Label&lt;/B&gt;&lt;/TD&gt;

&lt;TD&gt;&lt;B&gt;Value&lt;/B&gt;&lt;/TD&gt;
&lt;/TR&gt;

&lt;TR&gt;
&lt;TD&gt;Calendar Year&lt;/TD&gt;

&lt;TD&gt;="[Date].[Calendar Year].[Calendar Year].Members"&lt;/TD&gt;
&lt;/TR&gt;

&lt;TR&gt;
&lt;TD&gt;Reseller Business Type&lt;/TD&gt;

&lt;TD&gt;="[Reseller].[Business Type].[Business Type].Members"&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TABLE&gt;

&lt;P&gt;And the Rows parameters like this:&lt;/P&gt;

&lt;TABLE cellSpacing="0" cellPadding="0"&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;B&gt;Label&lt;/B&gt;&lt;/TD&gt;

&lt;TD&gt;&lt;B&gt;Value&lt;/B&gt;&lt;/TD&gt;
&lt;/TR&gt;

&lt;TR&gt;
&lt;TD&gt;Product Category&lt;/TD&gt;

&lt;TD&gt;="[Product].[Category].[Category].Members"&lt;/TD&gt;
&lt;/TR&gt;

&lt;TR&gt;
&lt;TD&gt;Sales Territory Country&lt;/TD&gt;

&lt;TD&gt;="[Sales Territory].[Sales Territory Country].[Sales Territory Country].Members"&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TABLE&gt;

&lt;P&gt;&lt;B&gt;Dataset&lt;/B&gt;&lt;/P&gt;

&lt;P&gt;Although the ultimate goal is to produce a dynamic MDX query, it's actually easier to start the design of the dataset using a static query and then to switch it out later. By using a static query, the fields for the dataset are autogenerated. The less work I have to do, the better.&lt;/P&gt;

&lt;P&gt;Now one thing about dynamic MDX in Reporting Services is the need to make sure the number of fields in the dataset are the same each and every time. Therefore I need to structure the query differently than I would if I were to write it for a "normal" Analysis Services client. That is, I need to rewrite a query like this:&lt;/P&gt;

&lt;PRE&gt;select&lt;/PRE&gt;
&lt;PRE&gt;non empty [Date].[Calendar Year].[Calendar Year].Members on columns,&lt;/PRE&gt;
&lt;PRE&gt;non empty [Product].[Category].[Category].Members on rows&lt;/PRE&gt;
&lt;PRE&gt;from [Adventure Works]&lt;/PRE&gt;
&lt;PRE&gt;where [Measures].[Sales Amount]&lt;/PRE&gt;&lt;DIV&gt;which produces a result like this:&lt;/DIV&gt;&lt;DIV&gt;&lt;A href="http://blog.datainspirations.com/wp-content/uploads/2010/10/StandardQueryResults.png"&gt;&lt;IMG class="alignnone size-full wp-image-250" title="Standard Query Results" alt="" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/StandardQueryResults.png" width="447" height="97"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;DIV&gt;to a query that looks like this:&lt;/DIV&gt;
&lt;PRE&gt;&lt;DIV&gt;select&lt;/DIV&gt;
&lt;DIV id="_mcePaste"&gt;[Measures].[Sales Amount] on columns,&lt;/DIV&gt;
&lt;DIV id="_mcePaste"&gt;non empty&lt;/DIV&gt;
&lt;DIV id="_mcePaste"&gt;([Product].[Category].[Category].Members,&lt;/DIV&gt;
&lt;DIV id="_mcePaste"&gt;[Date].[Calendar Year].[Calendar Year].Members)&lt;/DIV&gt;
&lt;DIV id="_mcePaste"&gt;on rows&lt;/DIV&gt;
&lt;DIV id="_mcePaste"&gt;from [Adventure Works]&lt;/DIV&gt;&lt;BR&gt;&lt;/PRE&gt;&lt;DIV&gt;and produces a result like this:&lt;/DIV&gt;&lt;DIV&gt;&lt;A href="http://blog.datainspirations.com/wp-content/uploads/2010/10/ModifiedQueryResults.png"&gt;&lt;IMG class="alignnone size-full wp-image-251" title="Modified Query Results" alt="" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/ModifiedQueryResults.png" width="246" height="237"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;DIV&gt;However, while structurally the result set is what I need, the fields generated for the dimensions above will change each time that I run the dynamic query with different specifications for rows and columns. So I need to modify the query one more time like this:&lt;/DIV&gt;
&lt;PRE&gt;&lt;DIV&gt;with&lt;/DIV&gt;
&lt;DIV&gt;member [Measures].[Measure] as [Measures].[Sales Amount]&lt;/DIV&gt;
&lt;DIV&gt;member [Measures].[RowValue] as [Product].[Category].CurrentMember.Name&lt;/DIV&gt;
&lt;DIV&gt;member [Measures].[ColumnValue] as [Date].[Calendar Year].CurrentMember.Name&lt;/DIV&gt;
&lt;DIV&gt;select {[Measures].[Measure], [Measures].[RowValue], [Measures].[ColumnValue]} on columns,&lt;/DIV&gt;
&lt;DIV&gt;non empty ([Product].[Category].[Category].Members, [Date].[Calendar Year].[Calendar Year].Members) on rows&lt;/DIV&gt;
&lt;DIV&gt;from [Adventure Works]&lt;/DIV&gt;
&lt;/PRE&gt;To get a result like this:&lt;DIV&gt;&lt;A href="http://blog.datainspirations.com/wp-content/uploads/2010/10/FinalModifiedQueryResults3.png"&gt;&lt;IMG class="alignnone size-full wp-image-257" title="Final Modified Query Results" alt="" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/FinalModifiedQueryResults3.png" width="704" height="158"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;DIV&gt;Now I can reference the generic Measure, RowValue, and ColumnValue in the report layout.&lt;/DIV&gt;
&lt;P&gt;&lt;B&gt;Matrix&lt;/B&gt;&lt;/P&gt;

&lt;P&gt;I like to test things out before I start introducing more complexity. So my next step is to add a matrix layout to the report design, and put fields into the layout and apply a little formatting as shown below.&lt;/P&gt;

&lt;P&gt;&lt;A href="http://blog.datainspirations.com/wp-content/uploads/2010/10/MatrixLayout1.png"&gt;&lt;IMG class="alignnone size-full wp-image-258" title="Matrix Layout" alt="" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/MatrixLayout1.png" width="357" height="73"&gt;&lt;/A&gt;&lt;/P&gt;

&lt;P&gt;One extra step related to formatting is required in my example. I have three possible measures, each of which uses a different format string. If I were displaying detail records, I could use the formatted_value cell property as an extended property in the textbox expression, replacing Fields!Measure.Value with Fields!Measure.FormattedValue. However, the use of a matrix here doesn't work with that approach, so... I need to create a conditional expression to set the Format property correctly:&lt;/P&gt;

&lt;PRE&gt;=Switch(Parameters!Measure.Label = "Sales Amount", "C2", Parameters!Measure.Label = "Order Quantity", "N0",&lt;/PRE&gt;
&lt;PRE&gt;Parameters!Measure.Label = "Gross Profit Margin", "P2")&lt;/PRE&gt;
&lt;P&gt;Then I preview the report to make sure all is well, which it is.&lt;/P&gt;

&lt;P&gt;&lt;B&gt;Query expression - step 1&lt;/B&gt;&lt;/P&gt;

&lt;P&gt;Now it's time to do the deed - convert the query string to an expression. To do this, I open Dataset Properties and click the expression button (fx) next to the Query box.&lt;/P&gt;

&lt;P&gt;The first step is just to enclose the query in double-quotes and prefix with an equal sign and to eliminate all the line feeds in the query. The expression needs to be one long string. If you really must add line feeds to make it easier to read, you can set up the expression like this:&lt;/P&gt;

&lt;PRE&gt;="with"&lt;/PRE&gt;
&lt;PRE&gt;+ " member [Measures].[Measure] as [Measures].[Sales Amount]"&lt;/PRE&gt;
&lt;PRE&gt;+ " member [Measures].[RowValue] as [Product].[Category].CurrentMember.Name"&lt;/PRE&gt;
&lt;PRE&gt;+ " member [Measures].[ColumnValue] as [Date].[Calendar Year].CurrentMember.Name"&lt;/PRE&gt;
&lt;PRE&gt;+ " select {[Measures].[Measure], [Measures].[RowValue], [Measures].[ColumnValue]} on columns,"&lt;/PRE&gt;
&lt;PRE&gt;+ " non  empty ([Product].[Category].[Category].Members, [Date].[Calendar Year].[Calendar Year].Members) on rows"&lt;/PRE&gt;
&lt;PRE&gt;+ " from [Adventure Works]"&lt;/PRE&gt;
&lt;P&gt;Just make sure to allow for a space between words on separate lines. I put it at the beginning of each new line so that I can see it easily. I then preview the report again to make sure that the expression works before I add in the next layer of complexity.&lt;/P&gt;

&lt;P&gt;&lt;B&gt;Query expression - step 2&lt;/B&gt;&lt;/P&gt;

&lt;P&gt;Next I plug in parameter values in the appropriate sections of the query, like this:&lt;/P&gt;

&lt;PRE&gt;="with"&lt;BR&gt;+ " member [Measures].[Measure] as " + Parameters!Measure.Value&lt;BR&gt;+ " member [Measures].[RowValue] as"&lt;BR&gt;+ " " + Split(Parameters!Rows.Value,"]")(0) + "]" + Split(Parameters!Rows.Value,"]")(1)+ "].CurrentMember.Name"&lt;BR&gt;+ " member [Measures].[ColumnValue] as"&lt;BR&gt;+ " " + Split(Parameters!Columns.Value,"]")(0) + "]"&lt;BR&gt;+ Split(Parameters!Columns.Value,"]")(1)+ "].CurrentMember.Name"&lt;BR&gt;+ " select {[Measures].[Measure], [Measures].[RowValue], [Measures].[ColumnValue]} on columns,"&lt;BR&gt;+ " non  empty (" + Parameters!Rows.Value + ", " + Parameters!Columns.Value + ") on rows"&lt;BR&gt;+ " from [Adventure Works]"&lt;/PRE&gt;
&lt;P&gt;Then I preview again. Here's the report with the default parameter settings: products on rows, dates on columns, and sales amount as the measure.&lt;/P&gt;

&lt;P&gt;&lt;A href="http://blog.datainspirations.com/wp-content/uploads/2010/10/DefaultParameterValues.png"&gt;&lt;IMG class="alignnone size-full wp-image-259" title="Default Parameter Values" alt="" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/DefaultParameterValues.png" width="750" height="97"&gt;&lt;/A&gt;&lt;/P&gt;

&lt;P&gt;And here's the report with sales territory on rows, business type on columns, and gross profit margin as the measure.&lt;BR&gt;&lt;A href="http://blog.datainspirations.com/wp-content/uploads/2010/10/ModifiedParameterValues.png"&gt;&lt;IMG class="alignnone size-full wp-image-260" title="Modified Parameter Values" alt="" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/ModifiedParameterValues.png" width="499" height="145"&gt;&lt;/A&gt;&lt;/P&gt;

&lt;P&gt;Mission accomplished!&lt;/P&gt;</description></item><item><title>Using Dynamic MDX in Reporting Services: Part 1</title><link>http://sqlblog.com/blogs/stacia_misner/archive/2010/10/07/29231.aspx</link><pubDate>Thu, 07 Oct 2010 16:40:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:29231</guid><dc:creator>smisner</dc:creator><description>&lt;p style="MARGIN:0in 0in 10pt;"&gt;If you're using Analysis Services as a data source for Reporting Services reports, you can build a simple dataset using the graphical query designer, but you'll want to switch to the generic query designer to create the MDX query string manually when you have more advanced requirements. Using the generic query designer, you can:&lt;/p&gt;&lt;p style="TEXT-INDENT:-0.25in;MARGIN:0in 0in 0pt 38.25pt;mso-add-space:auto;mso-list:l0 level1 lfo1;"&gt;· Impose greater control over the sets that you want to add to the rows axis by using set functions.&lt;/p&gt;&lt;p style="TEXT-INDENT:-0.25in;MARGIN:0in 0in 0pt 38.25pt;mso-add-space:auto;mso-list:l0 level1 lfo1;"&gt;· Add query-scoped named sets to the query in addition to calculated members. (Calculated members can also be added in the graphical query designer, but not named sets.)&lt;/p&gt;&lt;p style="TEXT-INDENT:-0.25in;MARGIN:0in 0in 10pt 38.25pt;mso-add-space:auto;mso-list:l0 level1 lfo1;"&gt;· Build dynamic MDX queries.&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;When would you need a dynamic MDX query? Whenever you want to modify the query based on a condition known only at run-time, typically based on a parameter value. If you're using the graphical query designer, you can auto-generate the report parameter's query for available values by selecting the Parameter checkbox. When the user selects a value during report execution, Reporting Services passes the unique name for the selection to the query and all is well. However, there might be situations when the user selection doesn't come from the cube, so you must find a way to convert the parameter value into a value that will work with the query.&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;In a series of posts, I will explore the available options for working with dynamic MDX queries in Reporting Services. By dynamic MDX, I mean that the query can be different each time it executes. In this post, I cover the use of &lt;a target="_blank" href="http://technet.microsoft.com/en-us/library/ms146022.aspx"&gt;StrToMember()&lt;/a&gt; and &lt;a target="_blank" href="http://technet.microsoft.com/en-us/library/ms144782.aspx"&gt;StrToSet()&lt;/a&gt; functions in parameters.&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;A very common scenario is the requirement to pass dates into a query. If you have a date filter for the report, do you really want users to navigate through a list of dates from the cube as shown below?&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;&lt;img style="WIDTH:177px;DISPLAY:inline;HEIGHT:212px;" height="212" alt="Date Parameter List" width="177" src="http://Blog.datainspirations.com/wp-content/uploads/2010/10/DateParameterList.png"&gt;&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;This list of dates - even if it's arranged hierarchically by month, quarter, and year - is what you get when you build the parameter directly from the date hierarchy in the query designer as shown below.&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;&lt;img style="WIDTH:624px;DISPLAY:inline;HEIGHT:243px;" height="243" alt="Graphical Query Designer" width="624" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/GraphicalQueryDesigner.png"&gt;&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;Wouldn't a more user-friendly experience allow the user to select a data from a calendar control? I can do this by changing the auto-generated report parameter's data type to a Date/Time data type and clear the "Allow multiple values" check box. I must also change the Available Values setting for the parameter to None. I can set the default value to "No default value" to force the user to make a selection, or do something nice like define an expression to set a date, like =Today().&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;So far, so good. But the problem now is that the date data type returned by the calendar control cannot be used by the MDX query without some intervention. I need to change the Parameter Value mapped to the query parameter in the Dataset Properties to an expression, like this:&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;="[Date].[Calendar].[Date].[" + Format(CDate(Parameters!DateCalendar.Value), "MMMM d, yyyy") + "]"&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt; &lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;&lt;img style="WIDTH:624px;DISPLAY:inline;HEIGHT:246px;" height="246" alt="" width="624" src="http://blog.datainspirations.com/wp-content/uploads/2010/10/DataSetProperties.png"&gt;&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;The expression that you use to convert a date like 2/1/2008 to a valid unique name in your Date dimension might look different. My example is specific to the Adventure Works 2008 R2 cube, which requires the date member to look like this: [Date].[Calendar].[Date].[February 1, 2008].&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;That's fine so far, but the result of this expression is a string and the MDX query requires a member or a set. The autogenerated query already makes this change for you fortunately. However, if you're creating your query manually, you should understand what it's doing, especially if you need to make changes to it.&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;The autogenerated query looks like this before I make changes:&lt;/p&gt;&lt;pre&gt;SELECT NON EMPTY { [Measures].[Sales Amount] } ON COLUMNS,&lt;/pre&gt;&lt;pre&gt;NON EMPTY { ([Product].[Category].[Category].ALLMEMBERS ) }&lt;/pre&gt;&lt;pre&gt;DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS&lt;/pre&gt;&lt;pre&gt;FROM ( SELECT ( STRTOSET(@DateCalendar, CONSTRAINED) ) ON COLUMNS&lt;/pre&gt;&lt;pre&gt;FROM [Adventure Works])&lt;/pre&gt;&lt;pre&gt;&lt;span style="COLOR:#ff0000;"&gt;WHERE ( IIF( STRTOSET(@DateCalendar, CONSTRAINED).Count = 1, &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="COLOR:#ff0000;"&gt;STRTOSET(@DateCalendar, CONSTRAINED), [Date].[Calendar].currentmember ) ) &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="COLOR:#ff0000;"&gt;CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS&lt;/span&gt;&lt;/pre&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;I prefer to simplify the query as shown below - removing the text highlighted in red text above. The function does what it says - changes the string (represented by the parameter @DateCalendar) into a set object. I remove the WHERE clause from the query as the FROM clause adequately restricts the query results to cell values related to the selected date. If I need the dimension properties in the report to display something or if I need the cell properties for report formatting, I'll include only the ones I need, but for this example I have removed them all from the query.&lt;/p&gt;&lt;pre&gt;SELECT NON EMPTY { [Measures].[Sales Amount] } ON COLUMNS,&lt;/pre&gt;&lt;pre&gt;NON EMPTY { ([Product].[Category].[Category].ALLMEMBERS ) } ON ROWS&lt;/pre&gt;&lt;pre&gt;FROM ( SELECT ( STRTOSET(@DateCalendar, CONSTRAINED) ) ON COLUMNS&lt;/pre&gt;&lt;pre&gt;FROM [Adventure Works])&lt;/pre&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;You could change the StrToSet() function to a StrToMember() function and get the same result. It's not harmful to leave StrToSet() as it is. It just returns a set of one member in this case-the date from the calendar control which is a valid set. The CONSTRAINED flag is used to prevent an injection attack and requires the expression to resolve to a valid member before the query executes.&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;One challenge that often confounds people working with MDX queries in the generic query designer is the inability to copy and paste the query into Management Studio for testing when parameters are in the query as shown above. The MDX query editor doesn't support parameters. Teo Lachev (&lt;a target="_blank" href="http://prologika.com/cs/blogs"&gt;blog&lt;/a&gt; | &lt;a target="_blank" href="http://twitter.com/tlachev"&gt;twitter&lt;/a&gt;) posted &lt;a target="_blank" title="How to Test SSRS MDX Queries in SQL Server Management Studio" href="http://prologika.com/CS/blogs/blog/archive/2009/07/06/how-to-test-ssrs-mdx-queries-in-sql-server-management-studio.aspx"&gt;some advice for working with parameterized MDX queries in Management Studio&lt;/a&gt; which I encourage you to check out.&lt;/p&gt;&lt;p style="MARGIN:0in 0in 10pt;"&gt;In my next post, I'll explain how to use the OLE DB for OLAP provider with dynamic MDX to create a dataset.&lt;/p&gt;</description></item></channel></rss>