I have a question about querying SQL from SSRS multi-value parameter.
My multi-value parameter is basically empty and depending on user-entered value so it is empty by default:
I try to make SQL query to query all data if no value is provided to the SSRS parameter and query only the data of the parameter if it is provided.
I tried these and none works so far:
SerialNumber IN (IIF(#SNList='', SerialNumber, #SNList)
SerialNumber IN (IIF(#SNList IS NULL, SerialNumber, #SNList)
SerialNumber IN (#SNList)
#1 works as I wanted to return all if the parameter is empty & if only one value is entered for the parameter but return an error if I entered more than 1 value (well, because when there are more than 1 value, we cannot use "=")
#2 will not return anything if no value is entered for parameter & if only one value is entered for the parameter but return an error if I entered more than 1 value.
#3 Works for multi/single values parameter
Is there a way to check number of values for the parameter or is there another way to make this works?
Multi-select parameters cannot be null, and to apply multi-select parameters SSRS will transform your query which would break if you tried to examine the variable in TSQL.
What you can do is introduce a second TSQL parameter that you set based on whether you should apply the main parameter. So your multi-select parameter #p1 is a string with a default value of "All", dataset query would be something like
if #p1IsNull = 1
begin
select *
from Sales.SalesOrderHeader
end
else
begin
select *
from Sales.SalesOrderHeader
where SalesOrderId in (#p1)
end
And #piIsNull is set with an expression
of the form
=iif( Parameters!p1.Value(0) = "All", 1, 0)
Depending on the parameter values, the SQL query will look like this:
exec sp_executesql N'if #p1IsNull = 1
begin
select *
from Sales.SalesOrderHeader
end
else
begin
select *
from Sales.SalesOrderHeader
where SalesOrderId in (N''43660'',N''43667'')
end',N'#p1IsNull int',#p1IsNull=0
or like this
exec sp_executesql N'if #p1IsNull = 1
begin
select *
from Sales.SalesOrderHeader
end
else
begin
select *
from Sales.SalesOrderHeader
where SalesOrderId in (#p1)
end',N'#p1IsNull int,#p1 nvarchar(3)',#p1IsNull=1,#p1=N'All'
Related
I am trying to run a SYSTEM$ABORT_SESSION(it could be ABORT_TRANSACTION) with provided parameter that is not literal:
SELECT SYSTEM$ABORT_SESSION(CURRENT_SESSION());
-- NULL
-- no effect, current_session() is an example, it could be read from metadata table
Similar with variable(no effect):
SET session_id = CURRENT_SESSION();
SELECT $session_id;
-- 70000000000
SELECT SYSTEM$ABORT_SESSION($session_id);
-- NULL
Next approach is using subquery(here more luck, as error message is more descriptive):
SELECT SYSTEM$ABORT_SESSION(s.session_id)
FROM (SELECT CURRENT_SESSION()) AS s(session_id);
-- non-constant input
SELECT SYSTEM$ABORT_SESSION(s.session_id)
FROM (SELECT $session_id) AS s(session_id);
-- non-constant input
The final approach, would be using stored procedure(also not possible due to side-effects):
CREATE OR REPLACE PROCEDURE abort_session(session_id FLOAT)
RETURNS varchar
LANGUAGE javascript
AS
$$
// same effect regardless of SQL concatenation/parameter binding
sql = 'SELECT SYSTEM$ABORT_SESSION(' + SESSION_ID + ')';
var rs = snowflake.execute({ sqlText: sql});
return 'Done';
$$;
CALL abort_session(CURRENT_SESSION());
-- Execution error in store procedure ABORT_SESSION:
-- SQL compilation error: Query called from a stored procedure contains a function with side effects
-- [SYSTEM$ABORT_SESSION]. At Snowflake.execute, line 3 position 23
It seems that the only way is to generate the query with literal, copy-paste and run(but this is the last resort).
Is there any other way to provide the input that could be determined during runtime?
Just a cast to int needed.
This returns null:
SELECT SYSTEM$ABORT_SESSION(CURRENT_SESSION());
This works as intended:
SELECT SYSTEM$ABORT_SESSION(CURRENT_SESSION()::int);
Screenshot:
I have some specific set of values that I want to filter on a column, I don't want to do an 'in' clause in SQL Server. I want to use loop to pass in different set of values each time.
For example if there is a name column in my data, and I want to run query 5 times with different filter value.
Please look at the loop query attached below.
DECLARE #cnt INT = 1;
WHILE #cnt < 94
BEGIN
SELECT Name, COUNT(*) AS Number_of_Names
FROM Table
WHERE name IN ('John')
AND value IS NOT NULL
GROUP BY Name
SET #cnt = #cnt + 1;
END;
I want to pass in different values under 'name' column at each loop like john in the case above, then mary in the next loop likewise based on set of values I pass in the variable like #values = John,Mary,Nicole,matt etc..
Considering the comments on your question, this should give you an idea on how to achieve a solution without using loops and still get all the names even when the name is not present on the table.
SELECT Name,
COUNT(value) AS Number_of_Names --Only count when value is not null
FROM (VALUES('John'), ('Mary'), ('Nicole'), ('Matt'))Names(name) --This can be replaced by a table-valued parameter or temp table.
LEFT JOIN Table t ON Names.name = t.name
--WHERE name IN ('John') /*No longer needed*/
--AND value IS NOT NULL /*Removed this because it would make the OUTER JOIN behave as an INNER JOIN*/
GROUP BY Name;
I am creating a SQL Server stored procedure. It's a simple SELECT query that I am building. One of the parameters is to look for a flag parameter. If that parameter is left blank, then the SELECT should default to NOT having the WHERE clause at all.
CREATE PROCEDURE sprocA
#flagInd int
AS
BEGIN
SELECT intID, strQuestion, strAnswer, intCategory, intOrder
FROM tblA
-- Right here is where I am looking for the logic of the #flagInd to be evaluated.....
-- if #flagInd = 1 then 'WHERE flgInd=1'
-- else if #flagInd=0 then 'WHERE flgInd=0'
-- else if #flagInd IS NULL then ''
It's just a simple query and a simple thought I had, not sure if it can be done without nesting and rewriting the whole SELECT statement as part of of the IF statement.
This can be done like:
SELECT intID, strQuestion, strAnswer, intCategory, intOrder
FROM tblA
WHERE flgInd = #flgInd OR #flgInd IS NULL;
You can also use a CASE expression:
SELECT intID, strQuestion, strAnswer, intCategory, intOrder
FROM tblA
WHERE CASE
WHEN flgInd = #flgInd THEN 1
WHEN #flgInd IS NULL THEN 1
ELSE 0
END = 1;
There appears to just be a one to one mapping (from the parameter to the column) so why not use a simple where clause?
CREATE PROCEDURE sprocA
#flagInd int
AS
BEGIN
SELECT intID, strQuestion, strAnswer, intCategory, intOrder
FROM tblA WHERE flgInd = #flagInd;
I am creating a report in SSRS that returns a bunch of data, one of the columns I need to return is a value from Active Directory. I have a query which gets a value that I want to pass into a subquery which looks a value up in Active Directory.
What I have so far looks something like this (simplified):
DECLARE #UserID int
SELECT #UserID = UserID FROM dbo.Users As TEST WHERE (RecordID = 123456)
(SELECT displayName FROM OpenQuery (
ADSI,
'SELECT displayName
FROM ''LDAP://DC=company,DC=local''
WHERE objectCategory=''user'' AND extensionattribute5='' +#UserID+ ''
') ) AS LoggedBy
FROM dbo.UserRecords WHERE UserID = 1
The problem is however when I use #UserID in the subquery the output alias "LoggedBy" always returns "Null". If I take the parameter out and manually type the value that the parameter has, it works fine.
It seems like I cannot get the #UserID paramter from the main query into the sub-query. ust wondering, what am I missing here?
You can't send variables into OpenQuery context in this way. Try to filter the query "outside":
DECLARE #UserID int
SELECT #UserID = UserID FROM dbo.Users As TEST WHERE (RecordID = 123456)
(SELECT t.displayName FROM OpenQuery (
ADSI,
'SELECT displayName, extensionattribute5
FROM ''LDAP://DC=company,DC=local''
WHERE objectCategory=''user''
') as t
WHERE t.extensionattribute5=#UserID ) AS LoggedBy
FROM dbo.UserRecords WHERE UserID = 1
From MSDN
OPENQUERY does not accept variables for its arguments.
Facing problem for generating SQL Server Query
In the Following query dynamic conditions are added to check whether value is null or not
Select *
From tblEmployees
where EmployeeName = Case
When #EmployeeName Is Not Null
Then #EmployeeName
Else EmployeeName
End
But I need to add IN () Conditions and the parameter with in the IN () could be null or blank also ,if the parameter /string which is passed to the IN condition is blank then i donot want to add that condition in the query.
So how can i Achieve this.A helping hand will be very useful for me.
Thanks and Regards,
D.Mahesh
Depending on value of your parameter (blank of not), you can create SQL string accordingly.
DECLARE #sqlCommand VARCHAR(1000)
IF(ISNULL(#YourParameter,'')='')
#sqlCommand = 'your query goes here'
ELSE
#sqlCommand = 'your query goes here'
and then, run it using dynamic query execution
EXEC (#sqlCommand)
If not dynamic query then,
SELECT ....
FROM ....
WHERE CASE WHEN ISNULL(#YourParameter,'')='' THEN '' ELSE EmployeeName END IN (ISNULL(#YourParameter,''))
See if this works...
I think the Dynamic query is the best solution, however you could put the "IS NULL" and "IS BLANK" condition in OR with your IN clause.
Something like that
Select *
From tblEmployees
where #EmployeeName is null or EmployeeName in (#EmployeeName)
When #EmployeeName is null, your IN clause will be ignored
If i get this right you have #EmployeeName = 'Name1,Name2,Name3' and you want to get the employees that is named Name1 or Name2 or Name3, also the variable #EmployeeName can be null or contain an empty string.
Instead of using IN you can split the string #EmployeeName on , and store it in a table variable or temporary table. Then you can use that table in a join against tblEmployees to get the rows you need.
There are a lot of posts in S.O. about how to split a string. Here is one recent variant.
Group by sql query on comma joined column
This will work for SQL Server 2005 or later.
declare #EmployeeName varchar(100) = 'Name2,Name3,Name5'
-- Null or empty will have a comma
set #EmployeeName = coalesce(#EmployeeName, '') + ','
-- cteNames splits the string to rows
;with cteNames
as
(
select
left(#EmployeeName, charindex(',', #EmployeeName)-1) as Name,
right(#EmployeeName, len(#EmployeeName)-charindex(',', #EmployeeName)) as EmployeeName
union all
select
left(EmployeeName, charindex(',', EmployeeName)-1) as Name,
right(EmployeeName, len(EmployeeName)-charindex(',', EmployeeName)) as EmployeeName
from cteNames
where charindex(',', EmployeeName) > 1
)
select E.*
from tblEmployees as E
inner join cteNames as N
on E.Name = N.Name or
#EmployeeName = ','
-- #EmployeeName = ',' will give you all names when #EmployeeName is null of empty