SSRS reporting executing cell data - reporting-services

So i'm not to sure how to research on this topic. My mission is to have a SSRS report execute a select query that is stored in a table. my table has a (select * from MyTable) in a column. What I need the report to do is when the hyperlink is clicked it will open a new tablix with all the data.
Any help we be appreciated.
Thank

I'm not sure what you are trying to do, but you can create dynamic SQL in your dataset query.
Put the SQL into a variable then execute it.
DECLARE #SQL VARCHAR(max)
SELECT #SQL = SQL_FIELD
FROM YOUR_TABLE
WHERE your criteria ...
EXEC(#sSQL)
After your SQL to set up your table, add your SELECT query.
You may have issues with permissions (as always) to EXEC.

Related

SSRS - Checking the UserID before allowing execution of report

I am using this code at the top of the SQL in my dataset for an SSRS report:
IF OBJECT_ID('tempdb..#ValidUsers') IS NOT NULL DROP TABLE #ValidUsers
CREATE TABLE #ValidUsers
(
ValidUsers Varchar(100),
)
Insert Into #ValidUsers SELECT 'ABC\UserA'
Insert Into #ValidUsers SELECT 'ABC\UserB'
Insert Into #ValidUsers SELECT 'ABC\UserC'
Then, I have this code that, at run time, pulls the current UserID into a variable #CurrentUser and I check if #CurrentUser is in my #ValidUsers temp table:
IF EXISTS (SELECT * FROM #ValidUsers WHERE ValidUsers = #CurrentUser)
Begin
... run SQL to retrieve data ...
Else
... don't retrieve the data ...
End
This is working just fine and only the users I specifically insert into #ValidUsers are able to run the report.
Is this acceptable - or is it a bad/insecure way to limit who can run an SSRS report?
If it is not good, what is the recommended way to restrict who can run a report?
You could create an user dataset in your report, then filter it by where name=#CurrentUser (set #CurrentUser's default value to User!UserID) in report. When the current user is in user dataset, the report will show, if its not in it, the report will show blank.
You could refer to this post for details.

How to Create Stored Procedures in SQL server 2008

Select tblppmp.idn
,tblppmp.total_item as a_total
,tblRequest.Quantity as b_total
,tblppmp.total_item - tblRequest.Quantity as itemsleft
FROM ppmp.dbo.tblppmp
INNER JOIN
(SELECT
tblrequest.idn
,sum(tblRequest.Quantity) AS Quantity
FROM ppmp.dbo.tblrequest
WHERE tblrequest.dr_year = 2015
GROUP BY tblrequest.idn) tblrequest ON tblppmp.idn = tblrequest.idn
Above is my code, how to create stored procedure and the value of the dr_year may change depending on the textbox or combobox selected by the user..sample is where tblrequest.dr_year = "Textbox1.text"
Whether the different value comes from a textbox or a combobox is irrelevant. It will always come into your stored procedure as a SQL parameter.
To create the Stored Procedure, simply execute the following on your database:
USE AdventureWorks
GO
CREATE PROCEDURE dbo.uspGetAddress
AS
SELECT * FROM Person.Address
GO
Replace the database name "AdventureWorks" in the USE command and the procedure name "uspGetAddress" in the CERATE PROCEDURE command with your database and procedure names respectively
Since you have a dynamic date value, you'll need to add the parameter. This changes your SQL code to look something more like this:
CREATE PROCEDURE dbo.uspGetAddress #Date datetime
AS
...
GO
Check out MsSQLTips for more info

Mysql select all existing tables from current database using stored procedure

I am still trying to solve this Mysql issue. I'm not a dba but need to figure out how to do it.
I need to run a select statement over all (50k) existing tables from current db.
Please note that union is not the correct way for me since I have more than 50k tables, I need to solve this with a loop.
So far, I have been trying with two approaches without success:
First: using a subquery and the information_schemma like:
Select *
from
(SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'my_db')
or
Select * from (show tables;);
Second: using a stored procedure like:
delimiter //
CREATE PROCEDURE get_all_tables()
BEGIN
DECLARE a varchar(100);
DECLARE cur1 CURSOR FOR SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'my_db';
OPEN cur1;
But neither is doing what I want.
It yields syntax or conceptual errors.
BTW: I already solve this using an external perl script performing a "show tables" and running a select withing a loop.
This is ok but I think this should be solved with pure mysql.
Any idea would be welcome.
Leo.
SELECT * FROM (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'my_db')
First of all, you can't do this in any implementation of SQL. The table name must be known by the query at prepare-time, not at run-time. You can't select from a string, you have to select from a table identifier.
It's the difference between these two queries:
SELECT * FROM MyTable -- identifier
SELECT * FROM 'MyTable' -- string value (this won't work)
By the way, most programming languages have a similar concept, of a function or class name being different from the name of that function or class. You can't execute a function by its name using the same syntax as you would execute it by its identifier.
<?php
$result = myFunction();
$result = 'myFunction'(); // nonsense
But some languages do have ways of getting around this:
<?php
$funcName = 'myFunction';
$result = $funcName();
In SQL, you can get around this limitation by using the table name as you build a new SQL query as a string. Then prepare and execute that SQL query string at runtime. This is called a dynamic SQL query.
But like the PHP example above of using a variable to store the name of the function, using dynamic SQL requires multiple steps. You can't combine the query to get your table names into the same query that uses the results.
You were on the right track with your stored procedure that opens a cursor for the set of table names. But you can't open cursors from dynamic SQL statements in stored procedures.
You can do what you need pretty easily using dynamic SQL in a scripting language like PHP or Python.

Multiple Datasets from Stored Procedure in SSRS

I have a stored procedure that returns multiple resultsets just as below
CREATE StoredProcedure sp_MultipleDataSets
AS
BEGIN
SELECT EMPID, ENAME, JOB, SAL, DEPTID FROM EMP -- first result set
SELECT DEPTID, DNAME, LOC FROM DEPT --second result set
END
In BIDS, while creating a new report I configured the stored procedure for dataset. It creates the dataset ONLY with the columns returned from the first result set. It does not identify the second result set.
How can I create datasets for both the result sets from a stored procedure like above
Unfortunately, as the documentation explains here:
If multiple result sets are retrieved through a single query, only the first result set is processed, and all other result sets are ignored.
(Found via this question.)
Therefore, I suggest using one of two possibilities:
(1) Split the procedure into two separate procedures - one which returns data from EMP, and one from DEPT - and access the new procedures as two separate datasets.
(2) Union the two separate queries (with an additional column to indicate which query produced each row) and filter or conditionally format your report appropriately. The unioned query might look something like this:
SELECT EMPID ID, ENAME NAME, JOB JOB_LOC, SAL, DEPTID, 'EMP' SOURCE
FROM EMP
UNION ALL
SELECT DEPTID ID, DNAME NAME, LOC JOB_LOC, NULL SAL, DEPTID DEPTID, 'DEPT' SOURCE
FROM DEPT
I use a Parameter in the SP to pull multiple Result sets in SSRS all the time.
You have to separate them by IF statements in the SP and also you then have to HAND TYPE out the FIELDS in the SSRS Dataset setup.
Seems whacky, but it works...
Here is a example.
Stored Procedure(SP) has 2 Parameters defined
#OfficerID
#DatasetFlag
The #OfficerID is the Employee # that has to be passeed or ENTERED IN (SSRS Data input form)
The DatasetFlag is the way I control which IF statement is executed in the SP.
so here is the SP:
CREATE PROCEDURE [dbo].[StoredProcedureNameHere]
#OfficerID VARCHAR(7),
#DatasetFlag VARCHAR(60)
WITH RECOMPILE
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT ON;
BEGIN TRY
IF #DatasetFlag = 'EmployeeName'
Begin
SELECT [EmployeeName]
FROM [DatabaseName].[scema].[Employee]
where EmployeeBNumber = #OfficerID
END
ELSE
IF #DatasetFlag = 'Expect'
Begin
SELECT
[TerritoryName]
,[TestNumber]
,[RuleNumber]
,[Expectation]
,[TestCount]
,[PercentToGoal]
FROM [Database].[scema].[Table2]
WHERE OfficerID = #OfficerID
ORDER BY TerritoryID
,TestNumber
,RuleNumber
END
RETURN
GO
The REPORT has 2 Datasets, one I create and it will pull in the parameters and EmployeeName
the other I create and it pulls in EmployeeName as SSRS can only use 1 Result SET~!
BUT.... I fool it ....
but I simpley CREATE the FIELDS by OVERTYPING the EMPLOYENAME and then ADD the
rest (Query) So Edit the FIELDS in the PROPERTIES of the DATASET and put in the Select Column Names.
Then I ese the PARAMETERS menu (Dataset Properties) to put in an EXPRESSION of ="EmployeeName"
for the first Dataset and ="Expect" for the 2nd. I match up the #OfficeID on that screen too.
then when I run this... it asks for OfficerID (RS creates the input form)
and when I put in the ID and hit VIEW REPORT. Or we can all the RDL with the OfficerID, just like the SSRS form does, but in an ASPX page.
BOTH DATASETS are returned (it calls it twice is my assumption)
So NO whacky FILTERING on a UNION dataset or other tricks that I have to then deal with in SSRS, which is not fun... (seriously IIF?)
I have see one Stored Procedure where we have like 20 Parameters , so you can filter
the OUTPUT of the report at the SQL level, rather than a monster pull and filter at the report.
No can you simply create 20 Stored Procedures, WELL YES, but this way, all the code is in ONE locations, and of course it can use selects into TEMP Tables to merge tons of stuff,
and in the end simply POPULATE a table that is the RESULT SET..
As a programmer I find SSRS a bit whacky, but so far I am having fun, trying to find ways to get what I want, not what it offers...
Try something like that:
Create StoredProcedure sp_MultipleDataSets(#Param nvarchar(10))
as
begin
if(#Param == "first")
begin
SELECT EMPID, ENAME, JOB, SAL, DEPTID FROM EMP -- first result set
end
if(#Param == "second")
begin
SELECT DEPTID, DNAME, LOC FROM DEPT --second result set
end
end
Here is one trick for this. This follows idea to Union All all the results for one table and works with SSRS repost with table
For each separate query add one column where is showing purpose of the query For e.g. "name" or "address", this info is repeated for each line of query.
Then Union All the wanted queries.
At Visual Studio / SSRS reporting: Add the dataset which contains storedprocedure. Then from tools select the tablix and drag the wanted data to tablix columns. Then go to tablix row properties -> Row visibility. for there make the sorting clause with IFF function to show only rows with previously defined extra column at queries, for e.g. "Name"
Then make the second tablix and follow the same, now use the IIF function with "Address", then continue as many different tables needed.

SSIS - Delete rows

I'm new to SSIS and need help on this one. I found an article which describes how to detect rows which exist and which have changed. The part that I'm missing is how to update rows that changed. I found some articles which say that it's also good solution to delete records which have changed and insert new recordset. The thing is I don't know how to do that step of deleting (red box).
Any suggestions?
If you have to delete the rows within Data Flow Task, then you need to use the OLE DB Command transformation and write a DELETE statement like DELETE FROM dbo.Table WHERE ColumnName = ?. Then in the column mappings of the OLE DB Command transformation, you will map the parameter represented by the question mark with the data that comes from the previous transformation. In your case, the data that comes from Union All 2.
However, I wouldn't recommend that option because OLE DB Command executes for every row and it might slow down your package if there are too many rows.
I would recommend something like this:
Redirect the output from the Union All 2 to a temporary staging table (say dbo.Staging) using OLE DB Destination.
Let's us assume that your final destination table is dbo.Destination. Now, your Staging table has all the records that should be deleted from the table Destination.
On the Control Flow tab, place an Execute SQL Task after the Data Flow Task. In the Execute SQL Task, write an SQL statement or use a stored procedure that would call an SQL statement to join the records between Staging and Destination to delete all the matching rows from Destination table.
Also, place another Execute SQL Task before the Data Flow Task. In this Execute SQL Task, delete/truncate rows from the Staging table.
Something like this might work to delete the rows:.
DELETE D
FROM dbo.Destination D
INNER JOIN dbo.Staging S
ON D.DestinationId = S.StagingId
Hope that helps.
In addition to user756519 answer. If you have millions of records to delete the last step (4) for ExecuteSQL Delete statement can be done in batches with something like this:
WHILE (1=1)
BEGIN
DELETE D
from dbo.Destination D
inner join
(
-- select ids that should be removed from table
SELECT TOP(10000) DestinationId
FROM
(
SELECT
D1.DestinationId,
S.StagingId
from
dbo.Destination as D1
LEFT JOIN
dbo.Staging as S
ON
D1.DestinationId = S.StagingId
) AS G
WHERE
StagingId IS NULL
) as R
on D.DestinationId = R.DestinationId;
IF ##ROWCOUNT < 1 BREAK
-- info message
DECLARE #timestamp VARCHAR(50)
SELECT #timestamp = CAST(getdate() AS VARCHAR)
RAISERROR ('Chunk deleted %s', 10, 1,#timestamp) WITH NOWAIT
END