Data Driven Subscriptions SSRS Standard Edition 2008 - sql

I'm fairly new to MSSQL and SSRS.
I'm trying to create a data driven subscription in MSSQL 2008 Standard SSRS that does the following.
Email the results of the report to a email address found within the report.
Run Daily
For Example:
Select full_name, email_address from users where (full_name = 'Mark Price')
This would use the email_address column to figure out who to email, This must also work for multiple results with multiple email address's.
The way I'm thinking of doing this is making a subscription to run the query, if no result is found then nothing happens.
But if a result is found then the report changes the row in Subscriptions table to run the report again in the next minute or so with the correct email information found in the results.
Is this a silly idea or not?
I've found a couple blog posts claiming this works but i couldn't understand their code enough to know what it does.
So, Any suggestions on how to go about this or if you can suggest something already out there on the internet with a brief description?

This takes me back to my old job where I wrote a solution to a problem using data-driven subscriptions on our SQL Server 2005 Enterprise development box and then discovered to my dismay that our customer only had Standard.
I bookmarked this post at the time and it looked very promising, but I ended up moving jobs before I had a chance to implement it.
Of course, it is targeted at 2005, but one of the comments seems to suggest it works in 2008 as well.

I've implemented something like this on SQL Server Standard to avoid having to pay for Enterprise. First, I built a report called “Schedule a DDR” (Data Driven Report). That report has these parameters:
Report to schedule: the name of the SSRS report (including folder) that you want to trigger if the data test is met. E.g. "/Accounting/Report1".
Parameter set: a string that will be used to look up the parameters to use in the report. E.g. "ABC".
Query to check if report should be run: a SQL query that will return a single value, either zero or non-zero. Zero will be interpreted as "do not run this report"
Email recipients: a list of semicolon-separated email recipients that will receive the report, if it is run.
Note that the “Schedule a DDR” report is the report we’re actually running here, and it will send its output to me; what it does is run another report – in this case it’s “/Accounting/Report1” and it’s that report that needs these email addresses. So “Schedule a DDR” isn’t really a report, although it’s scheduled and runs like one – it’s a gadget to build and run a report.
I also have a table in SQL defined as follows:
CREATE TABLE [dbo].[ParameterSet](
[ID] [varchar](50) NULL,
[ParameterName] [varchar](50) NULL,
[Value] [varchar](2000) NULL
) ON [PRIMARY]
Each parameter set – "ABC" in this case – has a set of records in the table. In this case the records might be ABC/placecode/AA and ABC/year/2013, meaning that there are two parameters in ABC: placecode and year, and they have values "AA" and "2013".
The dataset for the "Schedule a DDR" report in SSRS is
DDR.dbo.DDR3 #reportName, #parameterSet, #nonZeroQuery, #toEmail;
DDR3 is a stored procedure:
CREATE PROCEDURE [dbo].[DDR3]
#reportName nvarchar(200),
#parameterSet nvarchar(200),
#nonZeroQuery nvarchar(2000),
#toEmail nvarchar(2000)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
select ddr.dbo.RunADDR(#reportName,#parameterSet,#nonZeroQuery,#toEmail) as DDRresult;
END
RunADDR is a CLR. Here's an outline of how it works; I can post some code if anyone wants it.
Set up credentials
Select all the parameters in the ParameterSet table where the parameterSet field matches the parameter set name passed in from the Schedule A DDR report
For each of those parameters
Set up the parameters array to hold the parameters defined in the retrieved rows. (This is how you use the table to fill in parameters dynamically.)
End for
If there’s a “nonZeroQuery” value passed in from Schedule A DDR
Then run the nonZeroQuery and exit if you got zero rows back. (This is how you prevent query execution if some condition is not met; any query that returns something other zero will allow the report to run)
End if
Now ask SSRS to run the report, using the parameters we just extracted from the table, and the report name passed in from Schedule A DDR
Get the output and write it to a local file
Email the file to whatever email addresses were passed in from Schedule A DDR

Instead of creating a subscription to modify the subscriptions table, I would put that piece somewhere else, such as in a SQL agent. But the idea is the same. A regularly running piece of SQL can add or change lines in the subscription table.
A Google of "SSRS Subscription table" returned a few helpful results: Here's an article based on 2005, but the principles should be the same for 2008: This article is for 2008, and is really close to what you are describing as well.
I would just look at the fields one by one in the subscriptions table and determine what you need for each. Try creating a row by hand (a manual insert statement) to send yourself a subscription.

R-Tag supports SSRS data driven reports with SQL Server standard edition

You can use SQL-RD, a third-party solution, to create and run data-driven schedules without having to upgrade to SQL enterprise. It also comes with event-based scheduling (triggers the report on events including database changes, file changes, emails received and so on).

Related

Dealing with filtered Pass Through Query in MS Access

I have a relatively complex SQL query (complex to run in Access) and want to run it in MS Access. It works with the pass-through query well but going forward I will face an issue that is related to a filter I apply in the query. I select the current report date within the where function. Below is a part of my query I try to handle ;
select LS.PID_FACILITY, LS.ASOF_DTE, LS.DATA_CYCLE_FLG, LS.CUST_ACC, LS.CUST_SMUN, LS.CUST_NME, LS.CUST_CTY,
WHERE LS.ASOF_DTE='19-SEP-22'
I do not want to change asof_dte filter manually everyday. If this was a normal access query I could join another table that includes only the current report date. But I cannot do it in a pass-through query. What is the alternative way to do it? I read something about creating variables or strings, but I could not relate them to my problem, since I am a beginner at creating such solutions.
Thank you all.
Well, two VERY intresting things here.
First, YES a great idea to include the date in the PT query. But, you don't want to change that date each time.
Soluton:
Add a paramter to the query, and then from Access code add that paramter. It is VERY easy to do this (one line of code!!! - don't adopt the zillion examples out there that has a boatload of ADO code - NOT required!.
However, BEFORE we start dealing with above?
A MUCH better and simple, less work way to approach this?
in place of stored procedure?
if possbile, create a view. and use that for the report.
Why?
Because you then get TWO VERY valuable bonus.
First, you can freely use the reports "where" clause, and it respects the where clause and STILL runs server side!!!
In other words, create a view for that existing query, but WITHOUT the date set in that view.
You then link to the view from access client side.
Now, to open (filter) the report, you can do this:
docmd.OpenReport "MyReport",acViewPreview,,"LS.ASOF_DTE='19-SEP-22'"
Now, of couse the above "where" clause can be a varible (string).
NOTE SUPER but SUPER careful here:
If you base the reprot on a pass-though query (that then uses the stored procedure), then the filter occures CLIENT SIDE!!!! (all rows will be returned and THEN filtered if you report is based on that stored procedure.
But, if you use a view?
The the filter makes it to the server side!!!!
While both the pass-through query or the "view" can be filtered with the above "open report" and the where clause we have above?
The view will still filter server side - the pass-though query will NOT!!!
Now, the 3rd way, is of course to build the stored procedure to accept a date parmater.
You then could do this:
with Currentdb.QueryDefs("MyPassThoughQueryGoesHere")
.SQL = "EXEC MyStoreProc " + "19-SEP-22"
END WITH
docmd.OpenReport "MyReport",acViewPreview
So, you CAN add and have a PT query and add a paramter as per above.
However, unless that stored procedure has some speical code, you are MUCH better off to create a view server side, base the reprot on that view, and simple pass + use the traditional "where" clause of the open report command. Even if that view has no filter, returns all rows in the table?
With the "where" clause of the open report command, ONLY those rows meeting that critera will be pulled down the network pipe.
So, say a invoice table with 1 million rows.
Create a view, link the view in access.
base report on that view.
Now, do this:
docmd.OpenReport "rptInvoice",,,"InvoiceNum = 134343"
The above will ONLY PULL down 1 row from the server. Even if the view has no filter and would return 1 million rows.
So, using a view is less work then creating the stored procedure.
But, you can modify the stored procedure to accept a paramter, and then as noted use the above example to modify the PT query you have, and THEN open the report.
I think overall, it is less work to use view. Furthermore, if you have a slow running report now?
Replace the query (move it) to sql server side. Get it working. Now link to that view (give it same name as what the client side query was in Access).
Now, EVEN if you had some fancy filter code in VBA, and used openReport with the "where" clause? It will now work, only pull the records down the network pipe, you get stored procedure performance without the hassles. and the date format and "where" clause for open report is access/VBA style - not sql server style SQL.
So, high recommend you try and dump the stored procedure and use a view (and EVEN better is any where clause works - not just one based on pre-defined parameters for the stored procedure - so you not limited to parameters)
. However, no big deal - the above "EXEC dbo.MyStoreProce " & strDate example would also work fine if you have a date parameter you wish to supply to the pass-though query.

How can I schedule a script in BigQuery?

At last BigQuery supports using ; in the queries, so I can write more than one query in one "block", if I seperate them with semicolon.
If I run the code manually, it works. But I cannot schedule that.
When I want to schedule, I have two choices:
(New) Web UI: I must give a destination table. If I don't do it, I could not save the scheduled query. But all my queries are updates and inserts with different "destination tables". Like these:
UPDATE project.exampledataset.a
SET date = current_date()
WHEN TRUE
;
INSERT INTO project.otherdataset.b
SELECT c,d
FROM project.otherdataset.c
So I cannot even make a scheduling in the Web UI.
Classic UI: I tried this, because the official documentary states, that I should leave the "destination table" blank, and Classic UI allows it. I can setup the scheduling, but it doesn't run, when it should. I get the error message in email "Error status: Dataset specified in the query ('') is not consistent with Destination dataset 'exampledataset'."
AIK scripting (and using semicolon) is a very new feature in BigQuery, but I hope someone can help me.
Yes, I know that I could schedule every query one by one, but I would like to resolve it with one big script.
Looks like the scheduled query was defined earlier with destination dataset defined with APPEND/TRUNCATE type transaction. While updating the same scheduled query to a DML query, GUI doesn't show the dataset field / table name to update to NULL. Hence this error is coming considering the previously set dataset and table name in the scheduled query.
Hence the fix is to delete the scheduled query and create it from scratch with DML query option. It worked for me.
Scripting is supported in scheduled query now. However, scripting query, when being scheduled, doesn't support setting a destination table for now. You still need to use DDL/DML to make change to existing table.
E.g.:
CREATE OR REPLACE TABLE destinationTable AS
SELECT *
FROM sourceTable
WHERE date >= maxDate
As of 2022, the BQ Console UI will let you create a new scheduled query without a destination dataset, but it won't let you update a prior SELECT to use DDL/DML block syntax. However, you can use the BigQuery Data Transfer API to update the destinationDatasetId field, via transferconfigs/patch. Use transferconfigs/list to get the configId for a given scheduled query.
Note that you can either use the in-browser API Explorer, if you have the appropriate credentials, or write a programmatic solution. Also seems useful for setting/updating any other fields, including renaming scheduled queries.

SSRS Text Query: Variable names must be unique within a query batch or stored procedure

I am developing an SSRS 2008 report, but instead of using stored procedures, I want to use all Text queries. This report was working with stored procedures, but when I changed this report to use same logic but via text queries, I got the following error:
An error occurred during local report processing
    Query execution failed for dataset 'BRSR_Totals'
        The variable name '#END_yEAR' has already been declared. Variable names must be unique within a query batch or stored procedure.
Operation cancelled by user.
The problem is that some of my datasets (text queries) re-use the same parameters and END_YEAR is one of these parameters. How do I make this report run correctly?
One area that you might want to check is case sensitivity. SSRS is case-sensitive when considering parameter names but T-SQL does not have that case sensitivity. Take another look at your code and make sure that all parameters are using the same case.
I just resolved a similar issue using a text query to populate a dataset. It worked in SQL Server Management Studio and it worked in the Query Designer within BIDS, but failed at runtime.
The issue turned out to be BIDS helpfully adding parameters to the Dataset that this query was referencing. Switching to the Parameters tab of the Dataset Properties showed that BIDS had duplicated the parameters I had already added earlier. Deleting the duplicates resolved my problem.
To respond to the suggestion that the logic be off-loaded into a stored procedure: in this case, the report is a custom report for a single customer. The query will only ever be used in this report and makes a few assumptions about the customer's configuration that should not be available globally
I also just fixed this same issue in one of my queries. I was using a text query and had datetime variables/parameters. SSRS added a second set into the parameters for the dataset properties. I deleted them and my query ran fine after that and my graph populated.
I ran into a similar issue on a report where I had declare a substantial number of parameters at the beginning that I didn't want the end user to see. The issue I had was I was using a comma at the beginning of the line, so I had:
DECLARE #Parameter VARCHAR(4) = 'text'
, #Parameter VARCHAR(4) = 'text2'
It worked just fine in SSMS, but when I ran it in Report Builder 3.0 it threw the error shown in this thread. I changed it to remove the comma and to restate DECLARE at the beginning of each line and it worked perfectly.
Check that you didn't declare it twice, once in the CREATE PROC statement you're creating and another in the actual code...I've seen this problem while testing changes to SP code.

Using SQL Stored Procedure as data for a Microsoft Dynamics CRM report

We need to have a semi complex report in CRM that displays some accumulated lead values. The only way I see this report working is writing a stored procedure that creates a couple of temporary tables and calculates/accumulates data utilizing cursors. Then is the issue of getting the data from the stored procedure to be accessible from the Reporting Server report. Does anyone know if that's possible? If I could have the option of writing a custom SQL statement to generate report data, that would be just excellent.
Any pointers ?
Edit:
To clarify my use of cursors I can explain exactly what I'm doing with them.
The basis for my report (which should be a chart btw) is a table (table1) that has 3 relevant columns:
Start date
Number of months
Value
I create a temp table (temp1) that contains the following columns:
Year
Month number
Month name
Value
First I loop through the rows in the first table and insert a row in the temptable for each month, incrementing month, while setting the value to the total value divided by months. I.e:
2009-03-01,4,1000 in table1 yields
2009,03,March,250
2009,04,April,250
2009,05,May,250
2009,06,June,250
in the temp1 table.
A new cursor is then used to sum and create a running total from the values in temp1 and feed that into temp2 which is returned to the caller as data to chart.
example temp1 data:
2009,03,March,250
2009,04,April,200
2009,04,April,250
2009,05,May,250
2009,05,May,100
2009,06,June,250
yields temp2 data:
2009,03,March,250,250
2009,04,April,450,700
2009,05,May,350,1050
2009,06,June,250,1300
Last column is the running totals, which starts at zero for each new year.
Have you considered using views. Use a heirarchy of views if it is very complicated. Each view would represent one of your temporary tables.
EDIT Based on comments
I was thinking of SQL views, basically the same SQL as you would have written in your stored procedures.
I haven't done this - just thinking how I would start. I would make sure when the stored procedures populate the temporary tables they use the Filtered views for pulling data. I would then set the access to execute the SP to have the same security roles as the Filtered views (which should be pretty much to allow members of the PrivReportingGroup).
I would think that would cover allowing you to execute the SP in your report. I imagine if you set up the SP before hand, the SSRS designer has some means of showing you what data is available and to select an SP at design time. But I don't know that for sure.
First, since most cursors are unneeded, what exactly are you doing in them. Perhaps there is a set-based solution and then you can use a view.
Another possible line of thought, if you are doing something like running totals in the cursor, is can you create a view as the source without the running total and have the report itself do that kind of calculation?
Additionally, SSRS reports can use stored procs as a data source, read about how in Books online.
I found the solution. Downloaded Report Builder 2.0 from Microsoft. This allows me to write querys and call stored procedures for the report data.
Microsoft SQL Server Report Builder link

SQL Server Reporting Services 2005 - How to Handle Empty Reports

I was wondering if it is possible to not attach Excel sheet if it is empty, and maybe write a different comment in the email if empty.
When I go to report delivery options, there's no such configuration.
Edit: I'm running SQL Server Reporting Services 2005.
Some possible workarounds as mentioned below:
MSDN: Reporting Services Extensions
NoRows and NoRowsMessage properties
I should look into these things.
I believe the answer is no, at least not out of the box. It shouldn't be difficult to write your own delivery extension given the printing delivery extension sample included in RS.
Yeah, I don't think that is possible. You could use the "NoRows" property of your table to display a message when no data is returned, but that wouldn't prevent the report from being attached. But at least when they opened the excel file it could print out your custom message instead of an empty document.
Found this somewhere else...
I have a clean solution to this problem, the only down side is that a system administrator must create and maintain the schedule. Try these steps:
Create a subscription for the report with all the required recipients.
Set the subscription to run weekly on yesterday's day (ie if today is Tuesday, select Monday) with the schedule starting on today's date and stopping on today's date. Essentially, this schedule will never run.
Open the newly created job in SQL Management Studio, go to the steps and copy the line of SQL (it will look something like this: EXEC ReportServer.dbo.AddEvent #EventType='TimedSubscription', #EventData='1c2d9808-aa22-4597-6191-f152d7503fff')
Create your own job in SQL with the actual schedule and use something like:
IF EXISTS(SELECT your test criteria...)
BEGIN
EXEC ReportServer.dbo.AddEvent #EventType=... etc.
END
I have had success with using a Data-Driven Subscription and a table containing my subscribers, with the data-driven subscription query looking like this:
SELECT * FROM REPORT_SUBSCRIBERS WHERE EXISTS (SELECT QUERY_FROM_YOUR_REPORT)
In the delivery settings, the recipient is the data column containing my email addresses.
If the inner query returns no rows, then no emails will be sent.
For your purposes, you can take advantage of the "Include Report" and "Comment" delivery settings.
I imagine that a data-driven subscription query like this will work for you:
SELECT 'person1#domain.com; person2#domain.com' AS RECIPIENTS,
CASE WHEN EXISTS (REPORT_QUERY) THEN 'TRUE' ELSE 'FALSE' END AS INCLUDE_REPORT,
CASE WHEN EXISTS (REPORT_QUERY) THEN 'The report is attached' ELSE 'There was no data in this report' END AS COMMENT
Then use those columns in the appropriate fields when configuring the delivery settings for the subscription.