Change multiple SSRS data driven subscriptions for changing file shares - reporting-services

We have dozens of data driven subscriptions that we run manually at the beginning of the month that use file share delivery. They point to a certain server's shared drive.
That server is going away, so we need to either manually change the data driven sql that dynamically creates a path/filename for the dozens of subscriptions,
or we were hoping we could run an update statement or something? Below is kind of what we want to change. All instances of ATLACT02 to something else.
!!!!!!!!!!
Select 'Pro Bono Section ' + RTRIM(SECT_CODE) + ' ' + RTRIM(#PERIOD) AS 'FILE_NAME',
'\ATLACT02\Crystal Reports\Reports\Section\'+RTRIM(SECT_CODE) +'\'+ RTRIM(#PERIOD) AS 'PATH',
RTRIM(SECT_CODE) AS SECT,
RTRIM(#PERIODEND) AS PERIODEND,
RTRIM(#PERIODBEGIN) AS PERIODBEGIN
From _HBL_SECT SECT
Where SECT.INACTIVE = 'N' AND (SECT_CODE BETWEEN '100' AND '699')
AND SECT_CODE NOT IN ('101','201','301','401','501','601')

in your reporting services database
select * from Subscriptions where ExtensionSettings like '%ATLACT02%'
You can use some fancy TSQL to update the XML in that field or simply use the REPLACE
UPDATE Subscription
SET ExtensionSettings = REPLACE(ExtensionSettings,'ATLACT02','NewServerName')
WHERE ExtensionSettings like '%ATLACT02%'
Obviously a bit of testing would be pretty useful before attempting to change all your datadriven subscriptions

Related

SSRS - Trying to find all User Reports tied to a Batch File / Subscriptions

I have tried various queries I have found to try and accomplish this and none of them seem to list all the batch file/subscription instances tied to a user report in SSRS. If there is already a batch file out there tied to a user report, that's what I want to use versus creating a new batch file. I have tried going through the tables in the ReportServer database and looking for records to link to try and find this information, but I have been unsuccessful. Sorry if this is a simplistic question, but I have spent a few days trying to figure this out. Thank you!
You should be able to get at all subscriptions on your report server by running the following query:
You can alter this to suit your needs
use [ReportServer]
SELECT
R.Name
, L.TimeDataRetrieval
,L.TimeProcessing
,L.TimeRendering
, L.TimeDataRetrieval+L.TimeProcessing+L.TimeRendering AS TotalTime
,L.Format
,L.[Parameters]
,L.username
,L.TimeStart
,L.TimeEnd
,l.ReportID
,DATEDIFF(SECOND,L.timestart,L.timeend) time_seconds
,r.Path
FROM dbo.ExecutionLog L
INNER JOIN dbo.Catalog R
ON L.ReportID = R.ItemID
WHERE
R.Name like 'name of your report'

Captuing runtime for each task within a dataflow in SSIS2012

In my SSIS package I have a dataflow that looks something like this.
My requirement is to log the end time of each flatfile destination (Or the time when each of the flat files is created) , in a SQL server table. To be more clear, there will be one row per flatfile in the log table. Is there any simple way(preferably) to accomplish this? Thanks in advance.
Update: I ended up using a script task after the dataflow and read the creation time of each of the file created in the dataflow. I also used same script task to insert logs into the table, just to keep things in one place. For details refer the post masked as answer.
In order to get the accurate date and timestamp of each flat file created as the destination, you'll need to create three new global variables and set up a for-each loop container in the control flow following your current data flow task and then add to the for-each loop container a script task that will read from one flat file at a time the date/time information. That information will then be saved to one of the new global variables that can then be applied in a second SQL task (also in the for-each loop) to write the information to a database table.
The following link provides a good example of the steps you'll need to apply. There are a few extra steps not applicable that you can easily exclude.
http://microsoft-ssis.blogspot.com/2011/01/use-filedates-in-ssis.html
Hope this helps.
After looking more closely at the toolbox, I think the best way to do this is to move each source/destination pairing into its own dataflow and use the OnPostExecute event of each dataflow to write to the SQL table.
Wanted to provide more detail to #TabAlleman's approach.
For each control flow task with a name like Bene_hic, you will have a source file and a destination file.
On the 'Event Handlers' tab for that executable (use the drop-down list,) you can create the OnPostExecute event.
In that event, I have two SQL tasks. One generates the SQL to execute for this control flow task, the second executes the SQL.
These SQL tasks are dependent on two user variables scoped in the OnPostExecute event. The EvaluateAsExpression property for both is set to True. The first one, Variable1, is used as a template for the SQL to execute and has a value like:
"SELECT execSQL FROM db.Ssis_onPostExecute
where stgTable = '" + #[System::SourceName] + "'"
#[System::SourceName] is an SSIS system variable containing the name of the control flow task.
I have a table in my database named Ssis_onPostExecute with two fields, an execSQL field with values like:
DELETE FROM db.TableStats WHERE TABLENAME = 'Bene_hic';
INSERT INTO db.TableStats
SELECT CreatorName ,t.tname, CURRENT_TIMESTAMP ,rcnt FROM
(SELECT databasename, TABLENAME AS tname, CreatorName FROM dbc.TablesV) t
INNER JOIN
(SELECT 'Bene_hic' AS tname,
COUNT(*) AS rcnt FROM db.Bene_hic) u ON
t.tname = u.tname
WHERE t.databasename = 'db' AND t.tname = 'Bene_hic';
and a stgTable field with the name of the corresponding control flow task in the package (case-sensitive!) like Bene_hic
In the first SQL task (named SQL,) I have the SourceVariable set to a user variable (User::Variable1) and the ResultSet property set to 'single row.' The Result Set detail includes a Result Name = 0 and Variable name as the second user variable (User::Variable2.)
In the second SQL task (exec,) I have the SQLSourceType property set to Variable and the SourceVariable property set to User::Variable2.
Then the package is able to copy the data in the source object to the destination, and whether it fails or not, enter a row in a table with the timestamp and number of rows copied, along with the table name and anything else you want to track.
Also, when debugging, you have to run the whole package, not just one task in the event. The variables won't be set correctly otherwise.
HTH, it took me forever to figure all this stuff out, working from examples on several web sites. I'm using code to generate the SQL in the execSQL field for each of the 42 control flow tasks, meaning I created 84 user variables.
-Beth
The easy solution will be:
1) drag the OLE DB Command from the tool box after the Fatfile destination.
2) Update Script to update table with current date when Flat file destination is successful.
3) You can create a variable (scope is project) with value systemdatetime.
4) You might have to create another variable depending on your package construct if Success or fail

Is there anyway to change the body of an email subscription everyday?

I honestly don't think this is possible but I wanted to at least try. Everyday I have a report that is generated daily and sent out via SSRS email subscription to various people based on the transactions that I do in a proprietary program. Some days there are actually no transactions so it sends a blank excel file. I dont think it's supported natively so is there so way to hackily add the message "There were no transactions today" in the body of the email if there is no data in the excel file? and on days there is say something like "Transactions in attached Excel file"
So can someone please confirm. Is this possible? Or no?
Actually, this is natively possible and it is awesome! What you're looking for is a data driven subscription. You create one by going to the subscription tab under the management page for the report. There are two options: Create Subscription and Create Data-Driven Subscription. Click on the Create Data-Driven Subscription.
I apologize for the length from here but there is just so much to say about these!
I can't elaborate on the steps for everything here because it can be as in-depth a process to set up as you want it to be; there are a ton of options! Here's the MSDN article on Data-driven subscriptions, but you'll find it minimally helpful. Here's the TechNet Tutorial on how to create one, but I think you'll find that it doesn't delve as deep as you might like to go. I just learned everything by trial and error.
There's oh so much to say about these, but essentially you write a SQL query that evaluates something in your data and, as a result, gives the subscription different values for different variables, such as "Comments" (the body of the email written in html), "Include Report" (true/false), and "Render Format" to name a few.
It's important to note that for each line your query returns, one email will be sent. So if you wanted to send out three transaction report emails, you would want to make sure your query returns three rows with all the appropriate data.
For your own edification, here's a redacted copy of one of my queries that drives a report. You'll notice the comment field is quite long as it needs to be written in html. But SQL can handle the very long strings so long as you can formulate them correctly.
So, in your case, you would want to make Include_Report false when there are no transactions and then change the comment to a proper message about why no report is attached.
The purpose of this query is to look for server issues and if issues are found, send out an email (without the report attached) that tells end users it will be coming later. (I'm not in charge of the server performance and the people that are frequently don't fix it in time).
You'll notice that I have a field for every input variable into the SSRS subscription. This way, I can control how the report is emailed based on any script I can dream up. It also makes setup a little easier. I've also built in a quick way to test the subscription so I can play with it without it going to End Users and changing it to go out to end users takes seconds.
/*********************************************************/
/* Change #Testing to 'TEST' to have all emails */
/* sent to Christopher Brown */
/*********************************************************/
/* Change #Testing to 'PROD' to have all emails */
/* sent to normal recipients. */
/*********************************************************/
Declare #Testing varchar(4) = 'TEST';
With Problems as (
/*Script that looks for hardware failures or anything that would
cripple the accuracy of the report.*/
)
Select Case
When #Testing = 'TEST'
Then 'Just.Me#work.com'
When #Testing = 'PROD'
Then 'End.Users#work.com'
Else 'Just.Me#work.com'
End as 'To'
, Case
When #Testing = 'TEST'
Then 'Just.Me#work.com'
When #Testing = 'PROD'
Then 'IT.Group#work.com'
Else 'Just.Me#work.com'
End as 'CC'
, '' as 'BCC'
, 'Just.Me#work.com' as 'Reply-To'
, Case
When #Testing = 'TEST'
Then '***TEST***'
Else ''
End +
Case
When /*Problems Indicated*/
Then '#ReportName - Report Delayed'
Else '#ReportName for ' + CONVERT(varchar(10),getdate(),101)
End as 'Subject'
, 'Normal' as 'Priority'
, Case
When /*Problems Indicated*/
Then 'False'
Else 'True'
End as 'Include_Report'
, 'PDF' as 'Render_Format'
, Case
When /*Problems Indicated*/
Then 'High'
Else 'Normal'
End as Priority
, 'false' as 'Include_Link'
, Case
When /*Problems Indicated*/
Then '<html><Body><Font Face="Constantia","Times New Roman"><p>This Report could not be created at this time. We will send out an updated Report once the server issues have been resolved. If you have questions, please contact us.</p></Font></body></html>'
Else '<html><Body><Font Face="Constantia","Times New Roman"><p>Attached is the Report. When the report is run on a Monday, it does one thing.</p><p>Every other weekday, the report does something slightly different. Please note that the report is scheduled to run every weekday, Monday through Friday, regardless of holiday schedules.</p><p>If you have questions about the report, please contact us.</p><p>If the attached report is empty or missing vital information, click here to notify us.</p></Font></body></html>'
End as 'Comment'
From Problems

Shared data set for cached reports?

Is there a way in SSRS to create a snapshot for a report that uses a shared dataset? We are looking for a way to dynamically set the server and credentials in SSRS, but it seems when the shared dataset is used there is no way to cache a report.
Two things that I think may help you:
You can create a dynamic connection string from parameters you pass in. However you lose intellisense when creating this so generally I use an actual database first to do my dataset then change the connection string later:
A. Create a variable #Server, set it to text:
B. Create a local DataSource, this must be local as you cannot share a data source that is dynamic, to my knowledge as it has no input to go on thus a shared must have set inputs.
C. On the side of 'Connection string:' hit the 'fx' button to get a dynamic connection string. Build a connection string of text with your parameter being an input:
="Data Source=" & Parameters!Server.Value & ";Initial Catalog=(DBName)"
D. You NOW have to set up a dataset to bind to #Server variable or else someone just needs to do plain text to guess at a server. For this reason I usually create a dataset like
select 'Server1' as Server
union
select 'Server2'
union
select 'Server3'
You can handle the cache aspect COMPLETELY from the hosted end and not worry about the report stuff. Just go to a report once deployed and choose 'Manage'>'Snapshot Options'> Set your preferences.
EDIT: You probably want another variable for the database or else you will assume a same database structure all the time.

How to specify the report pdf name at run time?

I have a report named "Debt Report ". It runs for every month and a pdf is generated at the first of the month by subscription option.
If I am running the report for the month then the report name of the pdf should be "Debt Report for April" and like wise if I run it for may then the name of the pdf should be "Debt Report for May".
How can I do this?
Assuming you are scheduling the report to a file share, you can set the name of the file share to be Debt Report for #timestamp - this will name the file in the format Debt Report for YYYY_MM_DD_HRMINSS .
If you only want the month name (not the entire timestamp) to appear in the filename, you will need to use a Data Driven Subscription.
Another option, although a bit more technical, is to use the rs.exe utility to generate the report. This involves:
creating a script file that generates the report (this is where you can set the filename to your preference)
creating a batch file that calls rs.exe with the script file as a parameter
running the batch file on a schedule e.g. with Windows scheduler or SQL Server Agent
There is an example here of how to do this (to create Excel files but the principle is the same) http://skamie.wordpress.com/2010/08/11/using-rs-exe-to-render-ssrs-reports/
The solution for this problem is "Data Driven Subscription"
http://msdn.microsoft.com/en-us/library/ms169972(v=sql.105).aspx
http://www.kodyaz.com/reporting-services/create-data-driven-subscription-in-sql-server.aspx
the following link helped me alot but the query given in the link creates trouble- cast the datatype of the getdate and it will solve the problem
http://social.msdn.microsoft.com/Forums/en/sqlreportingservices/thread/0f075d9b-52f5-4a92-8570-43bbdaf2b2b1
I have had to do the same thing ( well almost )
I had to generate a weekly report to file and save it as REPORT-Week01.pdf, then REPORT-Week02.pdf etc.
The mechanism I used was to change the parameter column in the Schedule table via a scheduled job. This computed the required file name and simply replaced it. Then when the scheduled job runs, it writes to the file name setup when the schedule was created ( except that was changed at 1 minute past midnight to what I wanted it to be )
I have since implemeted another set of reports that write to a folder, whihc changes each month the the next months folder name ( currently writing all reports to a folder called 202103 ) tonight the job will run and the output folder will change to 202104 and the scheduled jobs will never need changing