I was needing to be able to pull a report based on who was logged in. For example, out of a group of salespeople, if Bob goes into this report and clicks on the Salesperson drop-down, I need him to only be able to see Bob as an available salesperson, not anyone else. I solved this by using the =User!UserID function in SSRS and it works beautifully.
Where I'm now having trouble is giving this functionality a CASE statement to allow an "Admin" view for managers to be able to go in and see Bob as well as everyone else. My current query looks like this and works as intended for only selecting that user's name from the Salesperson drop-down:
select SalesPerson_Name
from Salesperson
where salesperson_id = SUBSTRING(#user,14,20)
Here is what I'm attempting to use to override and give an 'All' type view for Admin level:
select Salesperson_name
from Salesperson
where case
when #user in ('DOMAIN\Brandyj','DOMAIN\jwilson') then 1=1
else SalesPerson_id = SUBSTRING(#user,14,20)
end
It does not like what I'm trying to do and gives me a
Incorrect syntax near '='.
Maybe I've been looking at this too long. Can someone spot something obvious?
You are close... just a minor change. You need the CASE expression to be evaluated on your operand of your SalesPerson_id column. CASE doesn't provide logical flow as you attempted to use it. Remember, it evaluates a set of boolean expressions to determine the result (which must be a single datatype).
I also opted for OR but you can still use IN if you'd like.
select Salesperson_name
from Salesperson
where
SalesPerson_id =
case
when #user = 'DOMAIN\Brandyj' or #user = 'DOMAIN\jwilson' then SalesPerson_id
else SUBSTRING(#user,14,20)
end
Related
I found this question on SO elsewhere, but the answer included a part that doesn't pertain to me, so I must ask this question with my specifics.
I need to simply add an option in my dropdown menu. Here's my SQL query to be used for the salesperson only (debug mode):
declare #user varchar(30)
set #user = 'DOMAIN\ppelzel'
select SalesPerson_Name
from Salesperson
where salesperson_id = case
when #user in ('DOMAIN\Brandyj',
'DOMAIN\jwilson','DOMAIN\KRoberts',
'DOMAIN\ppelzel','DOMAIN\bmurray')then salesperson_id
else SUBSTRING(#user,14,20)
end
order by 1
Per my previous mention of another question like this asked, it said to not use a WHERE clause. I, however, must use a WHERE clause because I need it to determine if the person logged in matches what's in the dataset, then that is the only name they'll see, outside of a handful of 'Admin' users who need to see everyone.
For these same Admin users, I need to add an option to select all salespeople. I tried simply using the "allow multiple values" but it doesn't like that and gives me an error: Incorrect syntax near ','. even when I take out the WHERE clause in my query of sp.salesperson_name = #salesperson. Anyway, what's my best course of action for adding an All option for this report?
EDIT: I just realized I might need to add the main dataset query for context:
SELECT sp.SalesPerson_Name
,c.Calendar_Month_Name
,sum(isnull(sales_qty, 0)) AS 'total gallons'
,sum(isnull(Ext_Retail_Base, 0) + isnull(Ext_Retail_Freight, 0)) - sum(isnull(Ext_Cost_Base, 0) + isnull(Ext_Cost_Freight, 0)) 'Sales GM'
,(sum(isnull(Ext_Retail_Base, 0) + isnull(Ext_Retail_Freight, 0)) - sum(isnull(Ext_Cost_Base, 0) + isnull(Ext_Cost_Freight, 0))) / sum(isnull(sales_qty, 0)) 'cpg'
FROM Fuel_Wholesale_Sales_Fact fwsf
JOIN calendar c ON fwsf.Calendar_key = c.calendar_key
JOIN Salesperson sp ON sp.SalesPerson_Key = fwsf.Salesperson_Key
JOIN Customer cu ON fwsf.Customer_Key = cu.Customer_Key
WHERE sp.SalesPerson_Name = #SalesPerson
AND c.Day_Date BETWEEN #Start
AND #End
and isnull(fwsf.sales_qty,0) != 0
GROUP BY sp.SalesPerson_Name, c.Calendar_Month_Name
UPDATE 1: I attempted to use the STRING_SPLIT function, but even using the simple example from Microsoft's website (https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-2016) resulted in me getting an error: Invalid object name 'STRING_SPLIT'. I am running SQL 2016. Thoughts?
Figured it out. Compatibility level issue. My DB is set on 110. I may need to ask some questions if there's a reason it's set on that as opposed to the default 130.
UPDATE 2: I finally sorted out what I needed. I just used the "Allow multiple values" option in the Parameter Properties. It wasn't working before because I foolishly did not use an IN operator nor surround the parameter with parentheses.
So I had the following: select salesperson where id = #salesperson
When what I needed was: select salesperson where id in (#salesperson) because Report Builder will pass a string of parameter values as 'Bob','Mary','John' which require that they be put inside the parentheses. This is for others who come looking for answers.
I'm creating a new report (*.rdl), and there I want to add username who runs the script (insert).
I've tried on VS2008 through "built-in-fields" function which is "User ID", but it didn't work:
CREATE TABLE #Some_Table
(
Plan_date date null,
Plan_customer int null,
creator_id nvarchar(55) null
)
INSERT INTO Some_Table
(
[Plan_date] ,
[Plan_customer],
[creator_id]
)
SELECT
#p_plan_monthly,
#p_plan_clients,
#creator_id ="user id" --from built-in-fields
Expected result is: Column creator_id is filling with value of username from active directory who made insert through my report.
To reiterate my comment, as it's is incredibly important:
"You need to use a different account to access your data #whitefang. The sa account should never be used for something as mundane as a report. In truth it should never be used unless you really need sysadmin privileges, or you're doing something like recovering the server. You should have a service account that can do the respective tasks it needs to. If you can suffer injection through those reports, you're service is like an open book to whomever has access."
Now, onto your problem. I would add a further internal parameter on your report. Change the value of the parameter to have the default value of =User!UserID; this will be the ID of the user running the report (perhaps something like StackOverflow\Larnu).
Then map that report parameter to your dataset parameter #creator_id and change your INSERT statement to:
INSERT INTO Some_Table ([Plan_date],
[Plan_customer],
[creator_id])
VALUES (#p_plan_monthly, #p_plan_clients, #creator_id);
Q: "and there I want to add username who runs the script (insert)"
You can use these functions.
-- database user name
SELECT USER_NAME()
-- login identification name
SELECT SUSER_NAME()
I want to use if else in where condition for Date Coulmns. Actually what i want to do is:
I have a table, which having two columns, CreatedDate and LastModifiedDate. Now what i want to check in Stored Proc is:
if LastUpdateDate is null then it will check for CreatedDate.
Below is my query:
SELECT isnull(SSA.UpdateDateTime,
isnull(SSA.CreateDateTime,'')) as LastUpdateAnswerDateTime
from SI_SurveySiteAnswer SSA
WHERE SSA.UpdateDateTime IS NOT NULL
There are other number of table in joins i am just pasting the required query only. how can i go for the check i am totally confused.
Please help me..
UPDATED:
I have write the below code, please confirm if it is the correct way to use If in where
SELECT isnull(SSA.UpdateDateTime,
isnull(SSA.CreateDateTime,'')) as LastUpdateAnswerDateTime
from SI_SurveySiteAnswer SSA
WHERE SSA.UpdateDateTime = ISNULL(SSA.UpdateDateTime,SSA.CreateDateTime)
I think i was not able to make my requirement very clear in first go, let me explain here..
i have a survey question answer table, i want to send an email notification if question has been answered, now answer can answered in one go, in that case createddate will have value not the updateddatetime,
Second case is:
answer is being updated in second go, then i need to check for the LastUpdateDateTime..
That's what i want to make in query.
You don't need any if / else functionality, just use the or operator to check that either is not null:
WHERE SSA.CreateDateTime is not null OR SSA.UpdateDateTime is not null
You can use COALESCE if you want this functionality, here are some sites for your reference.
http://www.mssqltips.com/sqlservertip/1521/the-many-uses-of-coalesce-in-sql-server/
http://sqlmag.com/t-sql/coalesce-vs-isnull
you can use case
SELECT Isnull(SSA.updatedatetime, Isnull(SSA.createdatetime, '')) AS
LastUpdateAnswerDateTime
FROM si_surveysiteanswer SSA
WHERE SSA.updatedatetime = CASE
WHEN SSA.updatedatetime IS NULL THEN
#SSA.createdatetime
ELSE SSA.updatedatetime
END
Try case statement.
SELECT isnull(SSA.UpdateDateTime,
isnull(SSA.CreateDateTime,'')) as LastUpdateAnswerDateTime
from SI_SurveySiteAnswer SSA
WHERE CASE WHEN SSA.UpdateDateTime IS NULL THEN SSA.CreateDateTime
ELSE SSA.UpdateDateTime END IS NOT NULL
I have a Column 'Status' which has values like Rework, Draft,Cancelled, Reviewed,Completed.
So in the prompt page i want a static choice with display value 'Treated' and 'Not treated'.
When the user selects 'Treated' then the "use values" should be 'Reviewed','Completed'
else if the user selects 'Not treated' it should be 'Rework',' Draft','Cancelled'. So how can we give multiple use values in static choice?
Please help!!!!
You need to create more advanced filter.
(?Selector? = 'Treated' and [Your column] in ('Reviewed','Completed'))
or
(?Selector? = 'Not treated' and [Your column] in ('Rework',' Draft','Cancelled'))
Where ?Selector? - you prompt variable.
Based on your comments, you need an if/then in your filter:
if (?Prompt? = 'Treated')
then ([column] in ('Reviewed','Completed'))
else
([column] in ('Rework','Draft','Cancelled'))
The OR suggestion below will work as well, I just personally find the if/then logic easier to read.
Excuse my language or SQL/Reporting wording
I am generating a report using Reporting Services where I have 2 drop down lists in order to show only by period and by category. I want it so if I select and I am shown all entries and if selected from any of the 2 drop downs then filter by those selections. I have a stored procedure which states the following on it's WHERE clause:
WHERE (dbo.PERIOD_LIST.PERIOD_DESC = #period) OR (dbo.CATEGORY.CATEGORY_DESC = #category)
However I cannot get this to work on Reporting Services/Visual Studio. I am shown ALL the entries instead of the filtered ones. I initialize #period and #category as NULL. So how can I make it so the report shows all rows when both attributes are null and still be able to filter by each or both of them?
How can I achieve this?
Edit: I used the suggestion Filip Popović gave me. If you're having this problem modify your prepared statement and make sure you refresh fields on your data sets since there's additional clauses on your prepared statement!
Note that in SQL, NULL = NULL is never evaluated to true. You can take it as NULL is not nothing it is something but unspecified. And You can't compare two unspecified values. You have to test COL1 IS NULL to get true if column has null value.
Try this:
WHERE ((dbo.PERIOD_LIST.PERIOD_DESC = #period) OR (#period IS NULL))
AND ((dbo.CATEGORY.CATEGORY_DESC = #category) OR (#category IS NULL))
Check the parameter for NULL as part of the condition:
WHERE ((#period IS NULL) OR (dbo.PERIOD_LIST.PERIOD_DESC = #period))
AND ((#category IS NULL) OR (dbo.CATEGORY.CATEGORY_DESC = #category))