Product Release Galore

Microsoft announced release dates for SQL Server R2, SharePoint 2010, Office 2010, and Visual Studio 2010.

  • According to the Microsoft SQL Server Team Blog: SQL Server 2008 R2 (aka SQL 2010) will be listed on Microsoft’s May price list, and will be available by May 2010
  • According the Microsoft SharePoint Team Blog: SharePoint 2010 and Office 2010 will be officially launched on May 12, 2010 with an RTM date of April 2010
  • Visual Studio 2010’s release date was pushed to April 12, 2010 due to some performance issues according to Developer Division’s Marketing and Communications Manager Rob Caron’s blog.

2010 is sure a busy year for BI!

Chasing Parameters

Scenario: You use the Visual Studio ASP.NET ReportViewer and you can’t figure out how to get the parameter values when the page posts back. I couldn’t find a straightforward answer on the discussion list so I thought my findings could come useful.

Solution: Depending on your scenario, you can choose one the following three approaches:

1. You can get the current parameter values after the ReportViewer.PreRender method completes. Use another event that fires after PreRender. Based on my testing, the only events I found out to work are ReportViewer.Unload or Page.Unload, e.g.:

protected void reportViewer_Unload(object sender, EventArgs e) {

    ReportViewer.ReportParameterInfoCollection parameters = reportViewer.ServerReport.GetParameters();

}

2. Subclass the control and override OnPreRender, calling the base method and then obtaining the parameter values.

3. If you are using Visual Studio 2010, the new ReportViewer exposes a new SubmittingParameterValues event for this purpose.

BIDS Integration Story in R2 – The Good, the Bad, and the Ugly

There was a huge discussion thread about the BIDS-Visual Studio integration story in the SQL Server 2008 timeframe where customers complained that BIDS got married with Visual Studio. This required switching both BI and code projects at the same if you want to have a solution with both project types. What has changed in R2?

The good – Report Server projects in BIDS R2 can target either SQL Server 2008 or R2, as explained in this blog. There is no change to Analysis Services projects. If you have a Report Server project with RDL 2008 files, the BIDS Report Designer won’t upgrade the report definitions. However, the moment you add a R2-specific feature, such as the new map region, BIDS will upgrade the report definition to R2 RDL. Therefore, if you want to play with R2 on your machine while the rest of the team is still on 2008 and you are careful, you can install R2 and upgrade BIDS without affecting the rest.

The bad – The R2 Report Server project format has changed to accommodate the new project deployment settings which are explained in the above-mentioned blog. The first time you open a Report Server project in BIDS R2, you will be asked to upgrade the project (not the RDLs). But what if you are forging new frontiers in your company (aka not following corporate standards) and decide to move to R2 while your peers are still on SQL 2008 assuming you use source control and share project files? No worries. BIDS 2008 will automatically strip out the elements in the report project file it doesn’t recognize. But when they save the project the project file will revert to the 2008 format, so you’ll get prompted again to upgrade the next time you load the project in BIDS. To solve this problem, I use a local project file.

The ugly – R2 doesn’t integrate with Visual Studio 2010 as it targets VS 2008 only. And since BI project types are part of BIDS and not Visual Studio, VS 2010 users won’t get the BI project templates either. In other words, you must have BIDS R2 and Visual Studio 2010 SxS. Consequently, you won’t be able to have a solution that spans both Visual Studio 2010 code projects and BI projects. This is like having one TV to watch US channels and a second TV to watch Euro.

It will be nice if one day the SQL Server setup program detects the Visual Studio version installed and ask you which version you want to integrate with. But given that Visual Studio project formats change between releases this may remain a wishful thinking.

Where is RDLOM in R2?

After covering the cool new stuff in R2, it’s time to talk about the uncool. One R2 change that really vexes me is RDLOM. RDLOM, short for Report Definition Language Object Model, lets developers program RDL in object-oriented way as opposed to using XML. RDLOM could save you a lot of effort when you have to meet more advanced requirements that involve pre-processing RDL. For example, in one of my projects we had to implement a wizard that would walk business users through steps to generate an ad-hoc report. Behind the scenes, the wizard would generate the report definition by using a custom RDLOM which we developed since back then Microsoft didn’t have their own. I included a scaled-down version of our implementation in my TechEd 2007 code sample. Although it took us a while to get our RDLOM implemented, it turned out to be invaluable down the road. Since we didn’t have to use XML API to manipulate RDL, it simplified programming RDL. For another project, we used RDLOM to let the customer specify which sections they want to see on the report. Once the selection was made, we would remove the unwanted sections from a report template. The list of real-life scenarios that could take advantage of RDLOM goes on …

Apparently, I wasn’t the only one bugging Microsoft about RDLOM that ships with SSRS and they promised that this will happen at TechED 2007 USA. Sure enough, SSRS 2008 brought us an unsupported version which I blogged about and covered more extensively in my Applied SSRS 2008 book. Although unsupported, the SSRS 2008 RDLOM was very useful. It was implemented in a single assembly (Microsoft.ReportingServices.RdlObjectModel.dll), exposed all RDL elements as objects, and supported serializing and deserializing RDL.

Alas, this will come to pass with R2. Upgrading to R2, you’ll find that the classes in Microsoft.ReportingServices.RdlObjectModel are marked as internal so you cannot use this assembly. Instead, RDLOM got moved into the Microsoft.ReportingServices.Designer.Controls.dll assembly. The good news is that there are rumors that RDLOM may get documented. Now the bad news:

  1. Clearly, R2 RDLOM was not meant to be distributed. While you need to reference explicitly only Microsoft.ReportingServices.Designer.Controls and Microsoft.ReportingServices.RichText assemblies you’ll find that they are dependent on other assemblies and you need to distribute a total of 25 assemblies resulting in a whopping 25 MB of referenced code. One way to avoid shipping so many assemblies to deploy your application in the BIDS or Report Builder 3.0 folders.

030910_0215_WhereisRDLO1

  1. R2 RDLOM will be 32-bit only because BIDS and Report Builder are 32-bit only.
  2. R2 RDLOM doesn’t support serializing the object model. I found a hack that uses .NET reflection to invoke the internal Serialize method of the old RDLOM 2008.

The RDLOM R2 C# console application bundled in this code sample demonstrates how you can use the “new” RDLOM. Besides referencing the new assemblies, you need to use the Load method to deserialize RDL to the object model:

report = Report.Load(fs);

And the above-mentioned hack to serialize it back to disk or stream.

using (FileStream os = new FileStream(ReportPath, FileMode.Create)) {

Assembly assembly = Assembly.GetAssembly(typeof(Report));

object mc = assembly.CreateInstance(“Microsoft.ReportingServices.RdlObjectModel.Serialization.RdlSerializer”);

Type t = mc.GetType();

MethodInfo mi = t.GetMethod(“Serialize”, new Type[] { typeof(Stream), typeof(Report) });

report = (Report)mi.Invoke(mc, new object[] { os, report });

}

Other than that, RDLOM remains virtually unchanged from 2008 excluding that it now supports the R2 enhancements to RDL. What if you don’t need this overhead but you need to make small changes to RDL that don’t necessarily require an object-oriented layer. I’ve found that the easiest way to do this and avoid XML programming is to use LINQ to XML. The LINQ to XML project included in the same sample demonstrates this approach. For example, the following code changes the data source reference of the first data source.

static void Main(string[] args) {

XElement report = XElement.Load(“report.rdl”);

string dns = “{“ + report.GetDefaultNamespace() + “}”;

XElement ds = report.Element(dns + “DataSources”).Element(dns + “DataSource”).Element(dns + “DataSourceReference”);

ds.Value = “/Data Sources/AdventureWorksAS2008”;

report.Save(“report1.rdl”); }

Not happy about the RDLOM story? Join the movement and vote for my suggestion on connect.microsoft.com to have a supported RDLOM.

How Windows UAC Got Me Again

User Access Control (UAC) is a feature of Windows Vista, Windows 7, and Windows Server 2008 that prevents you from running applications with administrator rights even if you are a local admin on the box. Although I have to admit I hate UAC, I am convinced that it’s better to have it around especially after my home desktop got infected a few months ago with a rootkit virus so badly that I had to restore the disk from a backup. So, UAC is a necessary evil. But since it’s relatively new, not many application developers test for UAC and this can get you as it happened in the following story.

A coworker complained that Reporting Services SharePoint integration doesn’t work on a distributed environment where SharePoint is installed on the front end Windows 2008 server and the SharePoint configuration database is installed on a separate database server. As usual, my first stop for troubleshooting SharePoint integration with Reporting Services was to examine the log file which gets generated after installing the Reporting Services Add-in for SharePoint, as I explained in this blog. On Windows Server 2008, the log file is located in the Temp folder of the user running the add-in setup, such as C:\Users\<user>\AppData\Local\Temp. To make the quest even more interesting, the AppData folder is actually hidden by default on Windows Server 2008 and Windows Vista/7 (another security gotcha), so you have to use Folder and Search Options to enable hidden files so you can see it. Are you having fun yet?

In this case, the log file showed an error:

User: SYSTEM

Installing Report Server feature.

Calling copyappbincontents command.

copyappbincontents command completed successfully.

Adding Report Server feature to farm.

Install error: The EXECUTE permission was denied on the object ‘proc_putObject’, database ‘IWSharePointCluster_Config’, schema ‘dbo’.

 

So, SharePoint can’t connect to the database server. What’s interesting is that the log file reported that the user is SYSTEM and not the logon of the interactive user. Luckily, Prash Shirolkar from the SSRS team blogged about this and provided a workaround for this issue which will get fixed in R2 RTM. Gotta love UAC…

New Reporting Services Data Providers

Two new data providers will be included in the SQL Server 2008 R2 release of Reporting Services, Microsoft SQL Azure and Microsoft SQL Server Parallel Data Warehouse, that will let you report from SQL Azure and SQL Server 2008 R2 Parallel Data Warehouse (code named Madison) databases respectively. I decided to take the Microsoft SQL Azure data provider for a spin. As you probably know by now, SQL Azure is a part of the Microsoft Windows Azure SaaS cloud offering. SQL Azure lets you host your SQL Server relational databases in the Microsoft data centers that provide scalability and fault tolerance services. This is great for companies of all sizes which don’t have resources or expertise to purchase and configure expensive hardware and software in order bo build scalable and highly available solutions. IMO, SQL Azure will be increasingly important, especially after Reporting Services and Analysis Services become available on SQL Azure although Microsoft doesn’t say yet when this will happen. At this point, you can only use Reporting Services as a client to author reports from SQL Azure-hosted databases.

Strictly, speaking if your database is hosted in SQL Azure, you can use the SQL Server or OLE DB providers (already included in Reporting Services) to send queries to SQL Azure. Just like on-premise solutions, SQL Server Azure clients retrieve data using the native SQL Server Tabular Data Stream (TDS). However, if you decide to use the native SQL Server providers, you will run into some issues with retrieving SQL Azure metadata. Hence, Microsoft added the SQL Azure data provider. To test it out, I followed these steps:

  1. I signed up for SQL Azure. If you MSDN Universal subscriber, you can sign up to test SQL Azure for eight months for free.
  2. I deployed the AdventureWorksDW2008R2 and AdventureWorksLT2008R2 databases to my SQL Azure server. The Adventure Works database deployment scripts for SQL Azure are available on codeplex. They will create AdventureWorksDWAZ2008R2 and AdventureWorksLTAZ2008R2 database on your SQL Azure server.
  3. Installed SQL Server 2008 R2 Release Candidate which is not publicly available.
  4. Created a new report in BIDS. As usual, I added a data source and selected the Microsoft SQL Azure provider.022810_1539_NewReportin1
  5. In the Connection Properties dialog box, I entered the name of my SQL Azure server and my standard security credentials (Windows security is not supported on SQL Azure). For some reason, the database dropdown is not automatically populated so I had to enter the name of the database AdventureWorksDWAZ2008R2 manually.
  6. Once connectivity has been taken care of, life is as usual. The Graphical Query Designer (toggle the Edit as Text button if the generic query designer starts first) shows the database schema.

    022810_1539_NewReportin2

    One thing that surprised me was the performance of data retrieval. Even when I opted to get all data from FactInternetSales, which has thousands of rows, the query executed pretty fast.  One caveat though with this approach is that you have open port 1433 on your corporate network because this is the port SQL Server uses for client connections. This is not required if your application is installed on Windows Azure and connects to the SQL Azure database on the server.

Beware Hidden Calculated Members

Here is another one of those “by design” issues (see the Not All Calculated Members Are Born Equal blog for another recent gotcha) that are not documented but can sure waste you precious time figuring out. The issue was first submitted on connect.microsoft.com by Greg Galloway almost a year ago where it was left in an investigation phase (what can we do to get the SSAS team actually review the connect cases and post findings?). Then, I submitted a similar issue and official support case since I was 100% sure it was a bug and I needed a closure. Alas, Microsoft came back to declare it “by design”:

“…per feedback from several AS 2005 Beta customers, for compatibility with pre-existing AS 2000 behavior, AS 2005 RTM (and later releases) was changed to not include hidden calculated members in cell calculations and scopes (except when a hidden calculated member is explicitly referenced in the calculation scope).”

The issue affects hidden calculated members and scope assignments where a scope assignment simply ignores hidden calculated members if they are not explicitly referenced by the script. You can easily repro the issue by making the following changes to the Adventure Works script:

/*– Allocate equally to quarters in H2 FY 2005 ————————*/

CREATE
MEMBER
CURRENTCUBE.[Measures].[Visible Quota] AS
null,

FORMAT_STRING = “Currency”,

VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = ‘Sales Targets’ ;

CREATE
MEMBER
CURRENTCUBE.[Measures].[Invisible Quota] AS
null,

FORMAT_STRING = “Currency”,

VISIBLE = 0 , ASSOCIATED_MEASURE_GROUP = ‘Sales Targets’ ;

Scope

(

[Date].[Fiscal Year].&[2005],

[Date].[Fiscal].[Fiscal Quarter].Members

);


this = (ParallelPeriod

(

[Date].[Fiscal].[Fiscal Year], 1,

[Date].[Fiscal].CurrentMember

), [Measures].[Sales Amount Quota]) * 1.35;

Here, I created two identical calculated members with the only difference that the first one is visible and second one hidden. Then, execute the following query:

SELECT {[Measures].[Sales Amount Quota], [Measures].[Visible Quota], [Measures].[Invisible Quota]} on 0

FROM [Adventure Works]

WHERE [Date].[Fiscal].[Fiscal Quarter].&[2005]&[1]

And here are the results (surprise!):

011810_2304_BewareHidde1

The Visible Quota member is populated as it should be but Invisible Quota refuses to budge as the script simply ignores it. If the script scopes on the Invisible Quota member explicitly or you make it visible, then we get the expected results. Since the issue is by design and a fix won’t be available anytime soon, you should be very careful when you use hidden calculated members and expect them to be affected by scope assignments. I use often helper calculated members which I hide since they shouldn’t be visible to the end users. This issue hit me really hard after QA reported wrong results and your humble correspondent had to debug a cube with some 1000+ lines of code.

Report Builder 3.0 Edit Sessions

When Report Builder 2.0 shipped , it introduced local and server preview modes. If the report uses local references only, such an embedded data source(s), Report Builder 2.0 executes the query and renders the report locally just like the BIDS Report Designer. However, when the report uses a server reference, such as shared data source(s) or subreports that were saved on the server, Report Builder 2.0 would transparently upload and process the report on the server just like the Report Builder 1.0.

Report Builder 3.0 improves the performance of server preview mode by introducing edit sessions. An edit session is implicitly created when the user runs the report for the first time. Behind the scenes, Report Builder 3.0 calls the new CreateReportEditSession API to instruct the server to create an edit session. The server caches the report dataset(s) in the ReportServerTempDB database (not in memory) and uses the cached data for subsequent previews. In this respect, you can think of edit sessions as the *.data files that the BIDS Report Designer generates to cache the report data in order to speed up report preview. As long as you don’t make changes to the report that affect the data, such as changes to the dataset itself, data source, or parameters, the cached copy of the data is used by the report. This means that the user may not see changes that might have taken place in the database for the duration of the edit session. To make sure that the latest data is used, click the Refresh button on the Report Builder 3.0 toolbar. Refreshing the report discards the edit session and executes the database queries.

The administrator can configure two new server properties to manage edit sessions:

  • EditSessonCacheLimit – By default, the data cache can hold up to five datasets per report and user. Note that if the dataset is parameterized, each parameter combination counts as one dataset. If you use many different combinations of parameter values, the report might need more cached dataset copies. The administrator can allow this by increasing the EditSessonCacheLimit setting.
  • EditSessionTimeout – By default, an edit session lasts 7200 seconds (2 hours). The servers resets the session every two hours when the user previews the report.

011810_1424_ReportBuild1

Report Builder 3.0 edit sessions are a performance-related enhancement that makes server-side report preview more efficient.

Report Builder 3.0 Enhancements in R2 and SharePoint 2010 Mode

A couple of Report Builder enhancements in SharePoint 2010 integration mode caught my attention. First, Report Builder 3.0 now launches by default when the Open in Report Builder action is initiated inside SharePoint 2010. Previously, Report Builder 1.0 would be launched.

011310_0305_ReportBuild1

Second, if the report includes a drillthrough action to another report, the action now works when the action is initiated from Report Builder 3.0 preview mode. As it turns out, a drillthrough action is forwarded directly to SharePoint. Previously, a report drillthrough action will result in an error because the Report Builder would attempt to resolve the action locally.

ReportService2010 Endpoint

Here is a little gem for developers programming Reporting Services. SQL Server 2008 R2 brings a new web service endpoint, ReportService2010, which merges the functionalities of the ReportService2005 and ReportService2006 endpoints. The new endpoint can manage objects on a report server that that are configured for either native or SharePoint integrated mode. Previously, the ReportService2005 endpoint was used for managing objects on a report server that is configured for native mode and the ReportService2006 endpoint was used for managing objects on a report server that is configured for SharePoint integrated mode. This required code changes and retesting if the report server was re-configured in a different mode. These endpoints are now deprecated but still supported. The ReportService2010 endpoint includes the functionalities of both endpoints. When unsupported APIs in ReportService2010 are invoked, such as invoking the CreateLinkedReport API in SharePoint mode which doesn’t support linked reports, the endpoint will return an error that the operation is not supported.