Extending SSRS Data Sources
Introduction
SQL Server Reporting Services comes out of the box with a good few data sources. Microsoft SQL Server and Microsoft Analysis Services are the main ones I use, and you can pretty much connect to any other database product using OLEDB/ODBC. What can you do when you want to display in reporting services that does not come from a database ?
There are two common methods used to provide data extensibility with reporting services:
Method |
Description |
Pros/cons |
XML Data Source |
The XML data provider flattens the XML structure into a data set that can be accessed by the reporting engine. The flattening and integration with diverse Web services, Web pages, and arbitrary XML documents is powerful, but sometimes confusing. |
Pros Best choice for Web Services Can model non “flat” data structures Custom Dot.Net Code can be exposed as web service through ASMX Does not need rely on SQL Server Cons Needs to deploy to an IIS web server. I find this really annoying as I like a report to encapsulate all it needs without bits hanging off. Not as intuitive to work with as Dataset based sources |
custom Data Processing Extension |
Dot.Net Library that enables you to bridge a data source and a dot.net dataset. Modeled after a subset of the .Net Framework data provider but has some extensions such as server side aggregates One the Extension is deployed and registered in the configuration file it appears in the list of data sources in report designer. |
A simplified data access architecture, often with better maintainability and improved performance. The ability to directly expose extension-specific functionality to consumers. Best choice for complex extension which will be re-usable. Such as exposing a suite of data from non ODBC compatible source. Cons Complex to develop and fiddly to deploy, especially in web farm (deployed to each node) Not easily compatible with Report Builder. |
Rather than pull your data from reporting services you could just use the extensibility features of a supported DataSource to push the data to reporting services. There are two common routes here:
Method |
Description |
Pros/Cons |
Sql CLR / stored procedures |
Visual Studio “Database” Project used to write dot.net classes that can be registered in sql server 2005 as first class objects. Stored procedures, Table Values Functions, Scalar Functions are useful here. The DLL is loaded into the host database via the “create assembly” command and is then hosted within SQL Server. SQL Server creates one thread pool per user per assembly. You can also provide COM and external calls using legacy extended stored procedures (xp_*) in SQL Server. I generally avoid this in favour of sqlclr, although xp_cmdshell is still very handy. |
Pros Written in common dot.net language Best choice for Flat Data Integrated into T-SQL Query Language Hides complexity from Report Designer Data Source can be exposed to Report Builder through a Report Model. Scripted Deployment via t-sql Cons Requires sqlclr to be enabled (disabled by default) Largely limited to the 12 safe namespaces By their nature sqlclr functions that access heterogeneous data tend to not be “safe” so some CAS issues when loading into database. More suited to relational tabular format. |
SSAS Stored Procedures |
Dot.Net class library aka MDX extensions can be loaded into the “Assemblies” section of Analysis Services using the xmla <ObjectDefinition><Assembly> (See sample CubeInfo.xmla in example code) These functions can then be exposed within MDX to be used in the same way as calculated measures using XMLA |
Pros Written in common dot.net language Best choice for integrating with other OLAP data sources using MDX. Integrated into MDX Query Language Hides complexity from Report Designer, normal Analysis Services Data Source used. Deployed to SSAS Server rather than individual database Scripted deployment through xmla Cons Requires Assembly to be registered within Analysis Services. Data is exposed through MDX, which may be less familiar to report writers than SQL. |
The last and I guess most obvious way to get non standard data into a report is to data warehouse it: e.g write an ETL or custom code to transform the data into a relational format where reporting services can suck it up natively. The architectural “pivot point” on this approach is how real time you want the data and if you can feasibly maintain a copy for reporting.
Recently I have been trying quite a seemingly simple task: to display the currently running SSIS packages on a report. It would have been really cool if I could have brought this into SQL Server as sqlclr Table Valued Function so we could have syntax like “Select * FROM RunningDtsPackages(@Server)”, but alas this is not possible as the ManangedDTS namespace is not in the list of allowed external namespaces (even though it is technically part of the SQL product !), assumably this is because it references the windows.forms and many other namespaces itself. I’m working on implementing as a web service to expose XML instead.
Example
This example looks at how to take data only retrievable through dot.net and return in to Reporting Services through an Analysis Services Stored Procedure. The best use case for this is of course data that you want to join to olap data via MDX.
In this case I want to return meat data on an OLAP cube such as: Last Processed Time, Data Source, Server Name, Database Name, Build Number and current user.
This can pretty much be implemented in any one of the methods above, but for real time access to cube meta data it makes sense to use an Analysis Services stored procedure.
CubeInfo SSAS Stored Procedure (vb.net)
- Open Visual Studio 2005
- Start a New Class Library Project called “CubeInfoMDX”
- Add a reference to Microsoft.Analysis.AdoMdServer (msmgdsrv.dll). This is used to use the “Context” object to refer to current analysis services session.
- Add a reference to Microsoft.AnalysisServices (Microsoft.AnalysisServices.dll). This is used to create a new AMO session.
- Enter code to use AMO to return Last Processed Time
Imports System Imports System.Collections.Generic Imports System.Text Imports Microsoft.AnalysisServices Imports Microsoft.AnalysisServices.AdomdServer Namespace ASStoredProcs Public Class CubeInfo ''' <summary> ''' Returns Last Processed Date ''' </summary> Public Shared Function GetCubeLastProcessedDate() As DateTime Dim oServer As New Microsoft.AnalysisServices.Server Try oServer.Connect("Data Source=" + Context.CurrentServerID) Dim dtTemp As DateTime = oServer.Databases.GetByName(Context.CurrentDatabaseName).Cubes.GetByName(Context.CurrentCube.Name).LastProcessed oServer.Disconnect() Return dtTemp Catch ex As Exception Throw Finally oServer.Dispose() End Try '//return Context.CurrentCube.LastProcessed; //this doesn't work because of a bug: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=124606 End Function End Class End Namespace |
- Compile Project
- Connect to SQL Server Management Studio\Analysis Server
- Right Click on Assemblies and select New
- Enter Assembly path with security of “unrestricted”
- Test the MDX extension with the following MDX Query
- with member [Measures].[LastProcessed]
with member [Measures].[LastProcessed] as [CubeInfoMDX].GetCubeLastProcessedDate()
select {[Measures].[LastProcessed] } on columns from [Adventure Works] |
We Can Now Make Up Report:
- Add a new VS Project of Type “Report Server Project Wizard”
- Add shared data source called “AdventureWorksMDX”
- Click Design Mode in Query Builder and enter your MDX directly. Note that you can use the Graphical Query Designer if you add calculated measures in your cube for the extended measures. However I prefer not to tie the cube to the extensions.
- Add your column to report and call Report “CubeInfoMDX”
- You can now deploy and use you report.
In My sample project (attached) I've added some more meta data that you might want to bring into MDX using AMO such as: server name, database name, cube name, Data Source Name.
Conclusion
Microsoft SQL Server 2005 Reporting Services offers integration with heterogeneous environments through lots of routes, giving you some nice options for accessing non relational heterogeneous data.
There are some great samples of using Analysis Services Stores Procedure on CodePlex at:
https://www.codeplex.com/ASStoredProcedures
For more information:
Microsoft SQL Server Developer Center
Reporting Services: Using XML and Web Service Data Sources
https://msdn2.microsoft.com/en-us/library/aa964129.aspx
Reporting Services: Extending with SQLCLR
https://msdn2.microsoft.com/en-us/library/bb293147.aspx
Data Sources Supported by Reporting Services
https://msdn2.microsoft.com/en-us/library/ms159219.aspx
Tutorial: Using XML Data in a Report
https://msdn2.microsoft.com/en-us/library/ms345334.aspx
Implementing a Data Processing Extension
https://msdn2.microsoft.com/en-us/library/ms154655.aspx
Using an External Data Source with Reporting Services
https://msdn2.microsoft.com/en-us/library/ms152917.aspx
Comments
- Anonymous
March 15, 2008
PingBack from http://bordercrossingstatsblog.info/bob-duffys-blobby-blog-extending-ssrs-data-sources/