The idea is to create an ‘empty’ standard subscription in SSRS and then, using a stored procedure, manipulate the parameters and run the report.
First create a dummy subscription that isn’t scheduled to run:
Once the subscription is saved, you need to get the SubscriptionID from the report server. Use the following code:
SELET
c.Name AS
ReportName,
rs.ScheduleID
FROM ReportServer.dbo.[Catalog] c
INNER JOIN ReportServer.dbo.Subscriptions s ON c.ItemID = s.Report_OID
INNER JOIN
ReportServer.dbo.ReportSchedule
rs ON c.ItemID = rs.ReportID
AND rs.SubscriptionID = s.SubscriptionID
Where
c.Name = 'Subscription Name'
You’ll need the SubscriptionID when calling the report.
Next create the following stored procedure that will be
called to run the report(s):
(I found this SP on the internet, but can’t remember where so
can’t credit where it’s due), either way it has a couple of changes and I hope
it helps out other people)
USE [ReportServer]
GO
/****** Object:
StoredProcedure [dbo].[data_driven_subscription] Script Date: 04/11/2012 16:38:33 ******/
SET ANSI_NULLS
ON
GO
SET QUOTED_IDENTIFIER
ON
GO
ALTER procedure
[dbo].[data_driven_subscription_1_Param]
( @scheduleID uniqueidentifier,
@TO varchar (2000) = ' ',
@CC varchar (2000) = ' ',
@BCC varchar (2000) = ' ',
@ReplyTO varchar (2000) =
' ',
@BODY varchar (8000) = ' ',
@param1 varchar (256) = ' '
)
as
DECLARE
@ptrval binary(16),
@PARAMptrval binary(16),
@TOpos int,
@CCpos int,
@BCCpos int,
@RTpos int,
@BODYpos int,
@PARAM1Pos int,
@length int,
@subscriptionID uniqueidentifier
-- set the subscription ID
SELECT @subscriptionID = SubscriptionID
FROM ReportSchedule WHERE ScheduleID = @scheduleID
-- set the text point for this records Email info
SELECT @ptrval = TEXTPTR(ExtensionSettings)
FROM Subscriptions WHERE SubscriptionID = @subscriptionID
-- set the text point for this records Parameter info
SELECT @PARAMptrval = TEXTPTR(Parameters)
FROM Subscriptions WHERE SubscriptionID = @subscriptionID
-- set the start position for the TO Address
SELECT @TOpos = patindex('%|EmailTO|%', ExtensionSettings) - 1
FROM Subscriptions WHERE SubscriptionID = @subscriptionID
IF isnull(@TOpos, '') <> '' and @TOpos > 0 and len(@To) > 0
-- change the TO address
UPDATETEXT Subscriptions.ExtensionSettings
@ptrval
@TOpos
4
@To
-- set the start position for the CC Address
SELECT @CCpos = patindex('%|CarbonCopy|%', ExtensionSettings) - 1
FROM Subscriptions WHERE SubscriptionID = @subscriptionID
IF isnull(@CCpos, '') <> '' and @CCpos > 0 and len(@CC) > 0
-- change the TO address
UPDATETEXT Subscriptions.ExtensionSettings
@ptrval
@CCpos
4
@CC
-- set the start position for the BCC Address
SELECT @BCCpos = patindex('%|BlindCopy|%', ExtensionSettings) - 1
FROM Subscriptions WHERE SubscriptionID = @subscriptionID
IF isnull(@BCCpos, '') <> '' and @BCCpos > 0 and len(@BCC) > 0
-- change the TO address
UPDATETEXT Subscriptions.ExtensionSettings
@ptrval
@BCCpos
4
@BCC
-- set the start position for the REPLY TO Address
SELECT @RTpos = patindex('%|ReplyTo|%', ExtensionSettings) - 1
FROM Subscriptions WHERE SubscriptionID = @subscriptionID
IF isnull(@RTpos, '') <> '' and @RTpos > 0 and len(@ReplyTO) > 0
-- change the REPLY TO address
UPDATETEXT Subscriptions.ExtensionSettings
@ptrval
@RTpos
4
@ReplyTO
-- set
the start position for the BODY Text
SELECT
@BODYpos = patindex('%|Comment|%', ExtensionSettings) - 1
FROM
Subscriptions WHERE SubscriptionID = @subscriptionID
IF
isnull(@BODYpos, '') <> '' and @BODYpos > 0 and len(@BODY) > 0
-- change the REPLY TO address
UPDATETEXT Subscriptions.ExtensionSettings
@ptrval
@BODYpos
4
@BODY
-- set
the start position for the Parameter 1
SELECT
@PARAM1Pos = patindex('%|Parameter1|%', Parameters) - 1
FROM
Subscriptions WHERE SubscriptionID = @subscriptionID
IF
isnull(@PARAM1Pos, '') <> '' and @PARAM1Pos > 0 and len(@parameter1) > 0
-- change the Parameter 1 value
UPDATETEXT Subscriptions.Parameters
@PARAMptrval
@PARAM1Pos
4
@parameter1
-- run the job
exec msdb..sp_start_job @job_name =
@scheduleID
-- this give
the report server time to execute the job.
-- there is
probably a better way to do this, so let me know if you know it ...
WAITFOR DELAY '00:00:10'
-- now change
everything back so you can run this again
-- set
the start position for the TO Address
SELECT
@TOpos = patindex('%' + @TO + '%', ExtensionSettings) - 1
FROM
Subscriptions WHERE SubscriptionID = @subscriptionID
SELECT
@length = len(@TO)
IF
@length > 0
--
replace the addresses with the original |TO|
UPDATETEXT
Subscriptions.ExtensionSettings
@ptrval
@TOpos
@length
'|EmailTO|'
-- set
the start position for the TO Address
SELECT
@CCpos = patindex('%' + @CC + '%', ExtensionSettings) - 1
FROM
Subscriptions WHERE SubscriptionID = @subscriptionID
SELECT
@length = len(@CC)
IF
@length > 0
--
replace the addresses with the original |CC|
UPDATETEXT
Subscriptions.ExtensionSettings
@ptrval
@CCpos
@length
'|CarbonCopy|'
-- set
the start position for the TO Address
SELECT
@BCCpos = patindex('%' + @BCC + '%', ExtensionSettings) - 1
FROM
Subscriptions WHERE SubscriptionID = @subscriptionID
SELECT
@length = len(@BCC)
IF
@length > 0
--
replace the addresses with the original |BC|
UPDATETEXT
Subscriptions.ExtensionSettings
@ptrval
@BCCpos
@length
'|BlindCopy|'
-- set
the start position for the REPLY TO Address
SELECT
@RTpos = patindex('%' + @ReplyTO + '%', ExtensionSettings) - 1
FROM
Subscriptions WHERE SubscriptionID = @subscriptionID
SELECT
@length = len(@ReplyTO)
IF
@length > 0
--
replace the addresses with the original |RT|
UPDATETEXT
Subscriptions.ExtensionSettings
@ptrval
@RTpos
@length
'|ReplyTo|'
-- set
the start position for the BODY Text
SELECT
@BODYpos = patindex('%' + @BODY + '%', ExtensionSettings) - 1
FROM
Subscriptions WHERE SubscriptionID = @subscriptionID
SELECT
@length = len(@BODY)
IF
@length > 0
--
replace the addresses with the original |BD|
UPDATETEXT
Subscriptions.ExtensionSettings
@ptrval
@BODYpos
@length
'|Comment|'
-- set
the start position for the Parameter
SELECT
@PARAM1Pos = patindex('%' + @parameter1 + '%', Parameters) - 1
FROM
Subscriptions WHERE SubscriptionID = @subscriptionID
SELECT
@length = len(@param1)
IF
@length > 0
--
replace the addresses with the original |P1|
UPDATETEXT
Subscriptions.Parameters
@PARAMptrval
@PARAM1Pos
@length
'|Parameter1|'
You’ll notice the name of the SP ends with ‘1_Param’. To add more use the following code in the
relevant part of the SP:
-- set the start position for the Parameter 2
SELECT
@PARAM2Pos = patindex('%|Parameter2|%', Parameters) - 1FROM Subscriptions WHERE SubscriptionID = @subscriptionID
IF isnull(@PARAM2Pos, '') <> '' and @PARAM2Pos > 0 and len(@parameter2) > 0
-- change the Parameter 1 value
UPDATETEXT Subscriptions.Parameters
@PARAMptrval
@PARAM2Pos
4
@parameter2
SELECT @length = len(@param2)
IF @length > 0
-- replace the addresses with the original |P2|
UPDATETEXT Subscriptions.Parameters
@PARAMptrval
@PARAM1Pos
@length
'|Parameter2|'
It would be prudent to create a few versions of this SP with
carrying numbers of parameters to meet all your needs.
The next SP is the one that runs and controls your new
data-driven subscription capabilities.declare @ReportParameter varchar(50)
declare @email_address varchar(255)
declare cur_cursor cursor for (select report_parameter,email_address
from
server.[database].[dbo].[tablewith
data])
open cur_cursorFetch Next from cur_cursor into @ReportParameter, @email_address
While @@fetch_status = 0
begin
exec data_driven_subscription_1_Param
@scheduleID = 'FE98A2D4-4430-4D5C-806C-717470CB1332',
@TO = @email_address,
@CC = '',
@BCC = 'AdministrativeEmail@CompanyName.com',
@ReplyTO = 'RelevantTeam@YourCompany.com',
@BODY = 'Hello testing 123',
@param1 = @ReportParameter
Fetch Next from cur_cursor into @ReportParameter, @email_address
end
close cur_cursor
deallocate cur_cursor
This cursor uses a table directly, but you can create any
complicated query you wish to determinethe parameters and emails, just as you
would with a normal data-driven subscription.
Notice the @scheduleID – this is the scheduleID you
collected after you saved the standard report subscription.The above code can either be turned into an SP, or placed directly into a SQL Agent Job.
Once you have an Agent job to run this procedure you can schedule it when and as required.
Any questions please don’t hesitate to contact me.
