Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

Authors

Search

XML Feeds

Google Ads

« DBA SQLCLR ProceduresReplace Your Case When Then Else Syntax With the Sign Function In SQL Server »
comments
Rate Post:
submit to reddit Digg!FacebookDotnetkicks

I took some time off so apologize to readers for my lack of writing lately.

Today I thought I'd talk about the report manager and SSRS. Personally I'm not a big fan of it. It lands in there with SSMS and tasks like creating or modifying indexes. I use it when I need it really quick and it's the only thing I need to touch. If you have to modify or create a bunch of things it becomes very cumbersome and pretty much an annoyance. Any browser based front end is a dog. Sense report manager is just that, you can expect refresh issues, slow response and having to hit 30 "OK" buttons to get one thing saved. The nice thing about most SQL Server Services is they are controlled by system procedures, functions etc... This means in most cases you can utilize these same system objects to your advantage. One that I'll show you today is the create subscriptions procedure named, "CreateSubscription" for Reporting Services.

If you're are using SSRS and in a high reporting environment like most are, then you more than likely have dozens if not hundreds of subscriptions setup so reports are automatically delivered to users on a time basis. In most cases the business has critical tasks that reply on reports to be run at specific times. If those reports are not run at the exact time specified, there may be missed opportunities or missed issues that can be hidden by data later on. When I first started using SSRS years back I dreaded the task of creating a subscription for a report to run here and there through the day. It was time consuming and again, an annoyance. This lead me to run profiler and do a bit of reading on what SSRS does behind the scenes in report manager. Once I found the CreateSubscription procedure, creating a dozen scheduled subscriptions for days in the week was actually pretty easy.

To run this procedure I recommend first looking at it to see what is does. You should always follow this guideline anytime you try to use objects like this. Follow the train all the way through to the end result set. An example of a really big catch on why you should do this can be seen in the CreateSubscription procedure. In order to gather the records required to insert the SID's for the person creating the subscription, the procedure GetUserIDBySid is called given the authority type of 1 being sent. If you do not accurately gather your SID before calling the CreatSubscription, you will essentially force the GetUserIDBySid to insert another row for your SUSER_NAME value. That will essentially break down the integrity sense you will now have duplicates of your account listed in the Users table. So for this issue you should follow back to the Users table and see that the SID is stored as a varbinary(85) and you can gather that based on your SUSER_NAME value as such

  1. SET @my_usersid = (SELECT [SID] FROM ReportServer.dbo.Users WHERE UserName = suser_name())

Use this SID the modify and create user value.

The ExtensionSettings and Schedule are XML values so be careful on how you form them. THe best resource you will probably find on the XML values is by looking up the "CreateSubscription Method" on MSDN here

The one thing that is another catch is the StartDateTime is based on a datetime value with the time zone offset included. If this is not formatted correctly, the report subscription is created but the schedule will fail. This creates a mess and will require you to remove the entire subscription to clear it up. To format this datetime I use a SQLCLR UDF as shown below

  1. public partial class UserDefinedFunctions
  2. {
  3.     [Microsoft.SqlServer.Server.SqlFunction]
  4.     public static SqlString DateTimeTimeZoneOffset(DateTime datetime_sent)
  5.     {
  6.         return new SqlString(datetime_sent.ToString("yyyy-MM-ddTHH:mm:ss.fffzzzz"));
  7.     }
  8. };

You can then pass to this function a basic datetime value while only needing to worry about sending the time that you want over to it.

as such...

  1. SET @time_send = (SELECT dbo.DateTimeTimeZoneOffset(CAST('2009-06-25 08:00:00' AS DATETIME)))

So putting this all together you can come up with a script similar to the following. This tested will create a subscription for each day of the week to be sent out at 8:00 AM

  1. DECLARE @me NVARCHAR(260)
  2. DECLARE @now DATETIME
  3. DECLARE @time_send VARCHAR(35)
  4. DECLARE @schedule NVARCHAR(1000)
  5. DECLARE @report_id UNIQUEIDENTIFIER
  6. DECLARE @report_name NVARCHAR(425)
  7. DECLARE @my_usersid VARBINARY(85)
  8.  
  9. SET @report_name = '/{folder}/{reportname}'
  10. SET @report_id = (SELECT ItemID FROM ReportServer.dbo.CATALOG WHERE [PATH] = @report_name)
  11. SET @now = GETDATE()
  12. SET @me = SUSER_NAME()
  13. SET @my_usersid = (SELECT [SID] FROM ReportServer.dbo.Users WHERE UserName = suser_name())
  14. SET @time_send = (SELECT dbo.DateTimeTimeZoneOffset(CAST('2009-06-25 08:00:00' AS DATETIME)))
  15. SET @schedule = '<ScheduleDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  16.                             <StartDateTime xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">' + @time_send  + '</StartDateTime>
  17.                             <WeeklyRecurrence xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">
  18.                                 <WeeksInterval>1</WeeksInterval>
  19.                                 <DaysOfWeek>
  20.                                     <Monday>true</Monday>
  21.                                     <Tuesday>true</Tuesday>
  22.                                     <Wednesday>true</Wednesday>
  23.                                     <Thursday>true</Thursday>
  24.                                     <Friday>true</Friday>
  25.                                 </DaysOfWeek>
  26.                             </WeeklyRecurrence>
  27.                              </ScheduleDefinition>'
  28.  
  29. EXEC CreateSubscription @Report_Name=@report_name,
  30.             @id=@report_id,
  31.             @OwnerSid = @my_usersid,
  32.             @OwnerName=@me,
  33.             @OwnerAuthType=1,
  34.             @Locale=N'en-US',
  35.             @DeliveryExtension=N'Report Server Email',
  36.             @InactiveFlags=0,
  37.             @ExtensionSettings=N'<ParameterValues>
  38.                         <ParameterValue>
  39.                             <Name>TO</Name>
  40.                             <Value>enduser@emails.com</Value>
  41.                         </ParameterValue>
  42.                         <ParameterValue>
  43.                             <Name>BCC</Name>
  44.                             <Value>system_retention@dba.com</Value>
  45.                         </ParameterValue>
  46.                         <ParameterValue>
  47.                             <Name>ReplyTo</Name>
  48.                             <Value>NoReply@company.com</Value>
  49.                         </ParameterValue>
  50.                         <ParameterValue>
  51.                             <Name>IncludeReport</Name>
  52.                             <Value>True</Value>
  53.                         </ParameterValue>
  54.                         <ParameterValue>
  55.                             <Name>RenderFormat</Name>
  56.                             <Value>EXCEL</Value>
  57.                         </ParameterValue>
  58.                         <ParameterValue>
  59.                             <Name>Subject</Name>
  60.                             <Value>@ReportName was executed at @ExecutionTime</Value>
  61.                         </ParameterValue>
  62.                         <ParameterValue>
  63.                             <Name>IncludeLink</Name>
  64.                             <Value>True</Value>
  65.                         </ParameterValue>
  66.                         <ParameterValue>
  67.                             <Name>Priority</Name>
  68.                             <Value>NORMAL</Value>
  69.                         </ParameterValue>
  70.                          </ParameterValues>',
  71.             @ModifiedBySid = @my_usersid,
  72.             @ModifiedByName=@me,
  73.             @ModifiedByAuthType=1,
  74.             @ModifiedDate=@now,
  75.             @Description=N'Send e-mail to users and other descriptions',
  76.             @LastStatus=N'New Subscription',
  77.             @EventType=N'TimedSubscription',
  78.             @MatchData=@schedule,
  79.             @PARAMETERS=N'<ParameterValues />',
  80.             @Version=3

With all of this you can now create multiple subscriptions for the same report to run through the day while only changing the time entered. You can also modify this easily to utilize the method in a procedure. This makes it much cleaner and easier to dynamically send multiple times and multiple reports so you can create mass subscriptions with one call. I will try to get a well error handled and procedure like that up in the next few days for download.



*** If you have a SQL related question try our Microsoft SQL Server Programming forum or our Microsoft SQL Server Admin forum

About the Author

Ted Krueger has been working in development and database administration for 13+ years. Specialties range from High Availability and Disaster / Recovery setup and testing methods down to custom assembly development for SQL Server Reporting Services. Ted blogs and is also one of the founders of LessThanDot.com technology community. Some of the articles focused on are Backup / Recovery, Security, SSIS and working on SQL Server and using all of the SQL Server features available to create stable and scalable database services. Recent community contributions have been to organize SQL Saturday events in the Chicago-land to Milwaukee-land area for 2010 where he will also be speaking about various SQL Server topics. @onpnt
Social SitingsTwitterLinkedInLTD RSS Feed
1375 views
submit to reddit Digg!FacebookDotnetkicks

Comments and Feedback

3 comments

Comment from: Rafal [Visitor] Email
***--
Hi there,

interesting... but have you actually tested it?
What it did for me is it did in deed insert a schedule, although it would never run. I played around with it, and found out that if you then edit the schedule (from Report Manager) and even don't make any changes, just exit by clicking "OK" - it will run (provided that the original schedule time hasn't expired yet. I spent a couple of hours with SQL Server Profiler and manage to understand that when you create/edit a schedule with Report Manager it also executes a few other sprocs:
1. CreateSubscription
2. CreateTimeBasedSubscriptionSchedule
3. msdb.dbo.sp_add_job
4. msdb.dbo.sp_add_jobserver
5. msdb.dbo.sp_add_jobstep
6. msdb.dbo.sp_add_jobschedule

As you can see 3-6 are related to system jobs which seem to actually be responsible for initializing the RS schedules(?). At least that's how I understand it.

I managed to complete the script with the necessary steps 3-6 and it all works beautifully.

E-mail me if you'd like the code.

Regards,
Rafal
06/07/09 @ 09:12
Comment from: Rafal [Visitor] Email
***--
By the way, I've tested it on SQL 2005.
06/07/09 @ 09:17
Comment from: onpnt [Member] Email
Hey, thanks Rafal. You are absolutely correct. I failed to add in this blog the SQL Agent jobs that are linked to the subscriptions. Glad you pointed it out and posted it. :)
06/07/09 @ 09:32

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)