SSRS Getting Column Names from CTE in the Fields of a Dataset - reporting-services

I am running a query in SSRS that is using 2 common table expressions. The query runs fine in the query designer, but the when I press ok and the dataset is formed; the fields in the dataset are the columns in the select * statement inside the cte. How do I get the columns i created in the cte to show up in the fields of my dataset in the ssrs? Any help is much appreciated.
IF #FilterByEventCode IS NULL
BEGIN
SELECT *
FROM
dbo.Historywithqualityfilter(#FQN, '.Event Code,.Event Description',
Dateadd(mi, -10, #DateStart), #DateStop, 'good', 'KLN-FTVP')
END
ELSE
BEGIN
WITH t1(timestamp, eventcode)
AS (SELECT localtimestamp,
valueasstring
FROM dbo.Historywithqualityfilter (#FQN, '.Event Code',
Dateadd(mi, -10, #DateStart),
#DateStop, 'good', 'KLN-FTVP')
WHERE #FilterByEventCode = valueasstring),
t2(timestamp, eventdescription)
AS (SELECT localtimestamp,
valueasstring
FROM dbo.Historywithqualityfilter (#FQN, '.Event Description',
Dateadd(mi, -10, #DateStart), #DateStop, 'good',
'KLN-FTVP')
)
SELECT *
FROM t1 a
INNER JOIN t2 b
ON a.timestamp = b.timestamp
END

What I've noticed is that SSRS has problems getting all fields in such way even when you're in query builder and you set all the parameters so that the maximum of fields apear when you click on "Refresh Fields" it'll still do what it wants to do.
For me you have only two solutions, the first is to edit your query so that the maximum of fields apear no mater what parameters you enter, push refresh fields, and then change the query back to what it was (however be carful not to refresh the fields again so cancel any request from the report builder to do such a thing).
The second is to manually create the missing fields.

Related

SSRS 2008 R2 - all parameters multi value AND optional

I've got a report that has 6 parameters. All parameters need to be optional and 3 have to be multi-value. One of the optional parameters is a dropdown, the rest are manually keyed in text boxes.
The Where clause below works when there are multiple #VendorNum values and one #FullJA value, but fails with multiple #FullJA values regardless of the #VendorNum count.
Parameters:
#VendorNum - keyed manually by user (space delimited) - optional, can be multivalue
#FullJA - keyed manually by user (space delimited) - optional, can be multivalue
#BU - optional, can be multivalue - when #JA is populated, this will auto-populate, if #JA isn't populated it's a dropdown with all selected.
#JA3 - keyed by user - optional, single value
#StartDate and #EndDate - optional single values
select * from some_table
WHERE
/*FULL JA*/
(
SUBSTRING(VendorNum, PATINDEX('%[^0]%', VendorNum + '.'), LEN(VendorNum)
) IN (#VendorNum)
AND LEFT(JA, 7) IN (#FullJA)
AND BU IN(#BU)
AND #JA3 IS NULL
)
OR
/*DATE RANGE*/
(
SUBSTRING(VendorNum, PATINDEX('%[^0]%', VendorNum + '.'), LEN(VendorNum)
) IN (#VendorNum)
AND LEN(ISNULL(CONVERT(VARCHAR(20), Cleared_When), '0')) >= #ClearedOnly
AND ad.Audit_Publish_Date >= ISNULL(#StartDate, '2015-01-01')
AND ad.Audit_Publish_Date <= ISNULL(#EndDate, '2025-12-31')
AND BU IN (#BU)
AND #FullJA IS NULL
AND #JA3 IS NULL
)
/*BUS UNIT AND JA3*/
OR (
SUBSTRING(VendorNum, PATINDEX('%[^0]%', VendorNum + '.'), LEN(VendorNum)
) IN (#VendorNum)
AND BU IN (#BU)
AND ad.Audit_Publish_Date >= ISNULL(#StartDate, '2015-01-01')
AND ad.Audit_Publish_Date <= ISNULL(#EndDate, '2025-12-31')
AND LEFT(JA, 3) = (#JA3)
AND #FullJA IS NULL
)
/*BUS UNIT ONLY*/
OR (
SUBSTRING(VendorNum, PATINDEX('%[^0]%', VendorNum + '.'), LEN(VendorNum)
) IN (#VendorNum)
AND BU IN (#BU)
AND ad.Audit_Publish_Date >= ISNULL(#StartDate, '2015-01-01')
AND ad.Audit_Publish_Date <= ISNULL(#EndDate, '2025-12-31')
AND #JA3 IS NULL
AND #FullJA IS NULL
)
The dataset parameter values for #FullJA and #VendorNum are both
=IIF(InStr(Parameters!FullJA.Value," ")>0,SPLIT(Parameters!FullJA.Value," "),Parameters!FullJA.Value) and all params are set as NOT multivalue, with nulls allowed.
Any help would be greatly appreciated. I've written over 200 reports for this project and this is the only one that is really grinding my gears!
Thanks!
I would approach this by building up some temp tables / table variables, to hold the potentially multi-valued variables, and then joining to those tables. This has the advantage of you being able to insert all possible values, in the case they have omitted the variable. So, you'd split your strings and put them into those tables (something along the lines of this example) if given the variable, and otherwise just do an insert into to populate your temp table / table variable.
For a split function, I prefer something like this:
create FUNCTION [dbo].[Split] (#sep VARCHAR(32), #s VARCHAR(MAX))
RETURNS TABLE
AS
RETURN
(
SELECT r.value('.','VARCHAR(MAX)') as Item
FROM (SELECT CONVERT(XML, N'<root><r>' + REPLACE(REPLACE(REPLACE(#s,'& ','& '),'<','<'), #sep, '</r><r>') + '</r></root>') as valxml) x
CROSS APPLY x.valxml.nodes('//root/r') AS RECORDS(r)
)
GO
GRANT SELECT
ON OBJECT::[dbo].[Split] TO PUBLIC
AS [dbo];
I would then put those variables into a table using something like this (my separator is a ", "):
select ltrim(rtrim(ppl.Item)) as PersonName
into #gppl
from dbo.Split(', ', #PersonListForCompare) as ppl
You would do something more like:
select ltrim(rtrim(vnd.Item)) as VendorNum
into #vendorNums
from dbo.Split(', ', #VendorNum) as vnd
You would then join to that temp table just like any other table & use it to limit your results that way. In your case, you want to put in all vendors (possibly) if they didn't give you any input. So, you'd do something like:
create table #vendorNums (VendorName varchar(64)) --I have no idea, here, what this data looks like
if #VendorNum is not null and datalength(#VendorNum) > 0
insert into into #vendorNums (VendorNum)
select ltrim(rtrim(vnd.Item))
from dbo.Split(', ', #VendorNum) as vnd
else
insert into into #vendorNums (VendorNum)
select VendorNum
from dbo.Vendors
That said, I think that you could use your select from dbo.Split directly as a table in a join, rather than putting it into the temp table. Only problem would be you'd have to be sure you had data in there to split, or else you're going to have a bunch of combinations to get the right match-up of null parameters vs. filled ones.

Show blank or null values in my SSRS Report

I'm a newbie to SSRS Reporting Services. My report runs great except that it doesn't show null or blank cells. I know there are some. What should I add to this query to show the blank or null in the DistributionOwnerId? Thanks in advance!
SELECT Id,
CONVERT(varchar(10), DistributionDate, 101) AS DistributionDate,
DistributionDate AS OriginalDistributionDate,
MedDrugName AS DrugName,
MedDistributionSessionDescription AS Session,
DistributionOwnerId,
CASE a.[Status]
WHEN 0 THEN 'Success'
WHEN 1 THEN 'Refused By Inmate'
WHEN 2 THEN 'Inmate Did Not Show'
WHEN 3 THEN 'Inmate Not In Cell'
WHEN 4 THEN 'Security Lockdown'
WHEN 5 THEN 'Medication Held (State Reason)'
WHEN 6 THEN 'Medication Out Of Stock'
END AS Status,
Notes,
UserName,
(SELECT NoteText + ';' AS Expr1
FROM MARDistAddNotes AS c
WHERE (a.Id = MARDistributionId) FOR XML PATH('')
) AS AdditionalNotes
, InmateLastName
, InmateFirstName
, InmateNumber
FROM MARDistribution AS a
WHERE (Status > 0)
ORDER BY DistributionDate, Session
SELECT CONVERT (DATE, GETDATE()) 'Date Part Only'

SSRS Report Parameters passed out

I am currently building a number of logging and analysis tools to keep tabs on our SQL environment. We are currently using SQL Server 2014.
What I want to do is keep check of all the parameters that are passed to our reports during the day. All of the reports are currently using stored procedures so in my table or a select statement based on a table is output the stored procedure with the parameters for every time the report was run.
At the end of the day I would then like to be able to take the outputted statement and run it in SSMS without having to use the report. I have been looking at the ExceutionLogStorage table and the ExecutionLog view's and though it has most of the information that I need, the parameters are not in an easily usable state.
Has anyone done something similar to what I have described?
You need to add logging part in your original SP, for example:
Alter procedure a
(#parameter)
As
Begin
..
..
Insert into loggingTable(col)
Values(#parameter)
..
..
End
Then query directly against that loggingTable for getting the history of used parameters
A Google search around this topic quickly brought up the following blog post already identified by the OP as useful and shown below (this query itself is actually an expansion of work linked to by LONG's answer below)
SELECT TOP 1 ParValue
FROM (
SELECT els.TimeEnd
, IIF(CHARINDEX('&' + 'ParameterName' + '=', ParsString) = 0, 'ParameterName',
SUBSTRING(ParsString
, StartIndex
, CHARINDEX('&', ParsString, StartIndex) - StartIndex)) AS ParValue
FROM (SELECT ReportID, TimeEnd
, '&' + CONVERT(VARCHAR(MAX), Parameters) + '&' AS ParsString
, CHARINDEX('&' + 'ParameterName' + '=', '&' + CONVERT(VARCHAR(MAX), Parameters) + '&')
+ LEN('&' + 'ParameterName' + '=') AS StartIndex
FROM ExecutionLogStorage
WHERE UserName='UserName' -- e.g. DOMAIN\Joe_Smith
) AS els
INNER JOIN [Catalog] AS c ON c.ItemID = els.ReportID
WHERE c.Name = 'ReportName'
UNION ALL
SELECT CAST('2000-01-01' AS DateTime), 'ParameterName'
) i
ORDER BY TimeEnd DESC;
Both these approaches though really only give us a starting point since they (variously) rely upon us knowing in advance the report name and parameter names. Whilst we can quickly make a couple of changes to Ken Bowman's work to get it to run against all executions of all reports, we still have the problem that the query hardcodes the parameter name.
The parameters required to execute a report are stored on the Catalog table in the Parameter column. Although the column has a datatype ntext, it is actually storing an XML string. Meaning we can use an XPath query to get at the parameter names
with
CatalogData as (
select ItemID, [Path], [Name], cast(Parameter as xml) 'ParameterXml'
from Catalog
where [Type] = 2),
ReportParameters as (
select ItemID, [Path], [Name], ParameterXml, p.value('Name[1]', 'nvarchar(256)') 'ParameterName'
from CatalogData
cross apply ParameterXml.nodes('/Parameters/Parameter') as Parameters(p))
select *
from ReportParameters;
Executing this query will list all reports on the server and their parameters. Now we just need to combine this with Ken Bowman's query. I've gone with a CTE approach
with
CatalogData as (
select ItemID, [Path], [Name], cast(Parameter as xml) 'ParameterXml'
from Catalog
where [Type] = 2),
ReportParameters as (
select ItemID, [Path], [Name], p.value('Name[1]', 'nvarchar(256)') 'ParameterName'
from CatalogData
cross apply ParameterXml.nodes('/Parameters/Parameter') as Parameters(p))
select
els.TimeEnd
, c.[Name]
, rp.ParameterName
, iif(
charindex(
'&' + rp.ParameterName + '=', ParametersString) = 0
, rp.ParameterName, substring(ParametersString
, StartIndex, charindex('&', ParametersString, StartIndex) - StartIndex
)) 'ParameterValue'
from (
select
ReportID
, TimeEnd
, rp.ParameterName
, '&' + convert(varchar(max), Parameters) + '&' 'ParametersString'
, charindex(
'&' + rp.ParameterName + '=',
'&' + convert(varchar(max), Parameters) + '&'
) + len('&' + rp.ParameterName + '=') 'StartIndex'
from
ExecutionLogStorage
inner join ReportParameters rp on rp.ItemID = ReportID) AS els
inner join [Catalog] c on c.ItemID = els.ReportID
inner join ReportParameters rp on rp.ItemID = c.ItemID and rp.ParameterName = els.ParameterName;
Note that the parameter values are passed to the report as part of a URL, so you'll still need get rid the literal space encoding and so on. Also, this doesn't (yet...) work for multi-value parameters.

reference a calculated field in mysql view

Need to refer a calculated field again in the statement. Have used # to create a variable and call it back. the statement gives a error saying "#1351 - View's SELECT contains a variable or parameter" have created three variables and referred them twice. what need to be corrected in the statement
CREATE OR REPLACE view finvoice AS SELECT
`Item_tax`,
`Date`,
`Invoice_No.`,
`Order_Id`,
`Buyer_name`,
`SKU_Code`,
`Product`,
#`price` := (round((((fkdaily.`Invoice_Amount`/ fkdaily.`Quantity`)-fkdaily.`Shipping_Charge_per_item`)/1.05),2)) as `price`,
`Quantity`,
#`vat_total` := (#price)*0.05)*Quantity),2)) As `vat_total`,
#`shipping` := (`Shipping_Charge_per_item`*`Quantity`) As `shipping`,
' ' as `roundoff`,
#`price`+#'vat_total`+#`shipping` as final
`Order_Status`,
`Invoice_No.` as `Invoice_No.2` ,
`Date` as date2,
'update_sku' as `TALLY_SKU`,
'Customer Sales (f)' As `Ledger`,
'Shipping Charges fk' As `Shipping Ledger`,
'FPC' As `Portal`
From fkdaily

SSRS - Clicking View Report Button Returns Focus to Parameter with Value Unset

I'm trying to run a Report in SSRS 2012, it's set up, and all the code runs fine in SSMS. But in SSRS I get the following:
Fill in all the parameters
Press View Report
The following appears
As you can see, the ToDate Parameter field is asking for a value again.
The following is the code for the parameters:
Fiscal Parameter
SELECT
FiscalPeriodId
,FiscalPeriodName + ' - ' + [Status] + ' ' + Convert(varchar(15),ENDDate, 101) AS FiscalPeriodName
,FiscalPeriodId AS OrderId
FROM fin.FiscalPeriod
WHERE Status = 'Closed'
AND GeneralLedgerGroupId = #Location
UNION
SELECT
FiscalPeriodId
,'Current'
,9999999 AS OrderId
FROM fin.FiscalPeriod
WHERE Status IS NULL
AND GeneralLedgerGroupId = #Location
UNION
SELECT
0 AS FiscalPeriodId
,'AS of Specified Date' AS FiscalPeriodName
,10000000 AS OrderId
ORDER by OrderId DESC
Date Parameter
SELECT
CASE
WHEN fp.ENDDate IS NULL
THEN GETDATE()
ELSE fp.ENDDate
END AS ToDate
FROM fin.FiscalPeriod fp
WHERE FiscalPeriodID = #FP
UNION
SELECT
CASE
WHEN #FP IS NULL
THEN GETDATE()
ELSE NULL
END AS ToDate
ORDER BY ToDate DESC
I've searched the web and found one question on Stackoverflow which seemed to be the same question, but there was no answer to it (2012). Any suggestions?