SSRS email to only user with browser rights - reporting-services

Is there a way for to trigger sending the emails on demand by a user who only has Browser rights? Is there something within SSRS to control that feature.

This answer is a lot of guessing as you don't provide much info. If this answer is not helpful, please edit your question and describe your current workflow and where SSRS currently sits in that workflow.
If you are using a report as part of your workflow, in this hypothetical situation:
User submits and invoice somehow
Invoice gets printed via SSRS report and at this point is deemed 'processed'
Invoice "submitted by" user gets an email says their invoice has been processed
Now lets a assume you have a simple Invoice header table something like
InvoiceID Amount SubmittedBy Processed ProcessedBy
12345 456.78 dave#company.org NULL NULL
Assuming the Report to generate in the invoice has a dataset something like
SELECT * FROM InvoiceHeader h
JOIN InvoiceDetail d on h.InvoiceID = d.InvoiceID
WHERE h.InvoiceID = #InvoiceID
At the end of the dataset query we can simply add some extra code to update the header table and email the recipient (assumes dbmail is configured on the SQL Server)
So we will end up with a final dataset query that looks like this
SELECT * FROM InvoiceHeader h
JOIN InvoiceDetail d on h.InvoiceID = d.InvoiceID
WHERE h.InvoiceID = #InvoiceID
IF EXISTS(SELECT * FROM InvoiceHeader WHERE InvoiceID = #InvoiceID and Processed IS NULL) -- checks in case the Invoice is being printed for a 2nd time
BEGIN
-- update the header table
UPDATE InvoiceHeader SET Processed=1, ProcessedBy = CURRENT_USER WHERE InvoiceID = #InvoiceID
-- send en email
DECLARE #to varchar(100)
DECLARE #body varchar(1000)
SELECT
#to = SubmittedBy,
#body = 'Your invoice ' + #InvoiceID + ' for the amount of ' + CAST(Amount as varchar(30)) + ' has been processed by ' + #ProcessedBy
FROM InvoiceHeader WHERE InvoiceID = #InvoiceID
EXEC msdb.dbo.sp_send_dbmail
#recipients = #to,
#subject = 'Invoice processed',
#body = #body
END
NOTE: This is not tested as I've done this off the top of my head so there may be some silly errors but you should get the idea.

Related

Capturing Campaign through Ampscript in email giving duplicate records

Our requirement is to capture campaign information during send time through Ampscript. ask is to capture data extension name, jobid and publication list for every campaign(unique DE-Jobid pair). I am able to populate DE with details, however we see duplicate records with same DE-Jobid pair. find the snippet below
SET #Job_Id = jobid
SET #DE = _DataSourceName
SET #Publication_List = AttributeValue("_listname")
SET #Campaign_Name = emailName_
set #date = NOW()
set #campaign_found = LookupRows("Campaign_Details_CDT","Job_ID", #Job_Id,"Segment_Name", #DE)
set #rowcount = rowcount(#campaign_found)
IF(#rowcount == 0) THEN
InsertDE("Campaign_Details_CDT", "Job_ID", #Job_Id, "Campaign_Name", #Campaign_Name, "Segment_Name", #DE, "Sent_Date", #date, "Publication_List", #Publication_List)
ENDIF
]%%````
I will appreciate your help to find reason for this.

MySQL: Getting current row ID in update

So I'm working on this trigger that updates an account balance as soon as one of the transaction types logged on it is changed. Here is the query:
BEGIN
IF (OLD.debit != NEW.debit) THEN
UPDATE account,
(SELECT accountid,
sum(accountentry.amountaccountentry) AS total
FROM accountentry
WHERE accountentry.typeid = NEW.idaccounttype
AND accountentry.accountid = account.idaccount
GROUP BY accountentry.accountid) AS s
SET account.balanceaccount = IF(NEW.debit = 1, IF(s.total IS NOT NULL, balanceaccount - s.total * 2, balanceaccount), IF(s.total IS NOT NULL, balanceaccount + s.total * 2, balanceaccount));
END IF;
END
Now, this query does work if I remove the "AND accountentry.accountid = account.idaccount" part. Since I'm in some kind of "sub query", how would I go about retrieving the id of the account I'm currently updating?
Thanks a lot :)
I agree with the goal of keeping redundant data out of the database but I also understand that this is not always practical. In this case, retrieving the balance by aggregating the transactions should be very low cost if appropriate indices are in place. I do not know the details of your specific scenario but, at the very least, you should be very cautious when introducing redundant data. It will almost certainly become inconsistent at some point.
Having this update in a trigger, as opposed to plainly visible in a transaction in your application's code, is a likely source of hard to track bugs in the future.
You have not included enough information (CREATE TABLE statements, sample data, desired outcome) in your question for me to answer with confidence but I will have a go.
Your update query appears to be attempting to handle the scenario where the transaction type for one entry is being changed from debit to credit or vice versa but it does not allow for the amountaccountentry changing at the same time. I do not understand why you are using GROUP BY and SUM when you are only dealing with a change to one accountentry. Surely you could use -
BEGIN
IF (OLD.debit != NEW.debit AND OLD.amountaccountentry = NEW.amountaccountentry) THEN
UPDATE account
SET account.balanceaccount = IF(NEW.debit = 1, IF(NEW.amountaccountentry IS NOT NULL, balanceaccount - (NEW.amountaccountentry * 2), balanceaccount), IF(NEW.amountaccountentry IS NOT NULL, balanceaccount + (NEW.amountaccountentry * 2), balanceaccount))
WHERE idaccount = NEW.accountid;
END IF;
END
or if amountaccountentry could change at the same time -
BEGIN
IF (OLD.debit != NEW.debit) THEN
UPDATE account
SET account.balanceaccount = IF(NEW.debit = 1, IF(NEW.amountaccountentry IS NOT NULL, balanceaccount - (OLD.amountaccountentry + NEW.amountaccountentry), balanceaccount), IF(NEW.amountaccountentry IS NOT NULL, balanceaccount + (OLD.amountaccountentry + NEW.amountaccountentry), balanceaccount))
WHERE idaccount = NEW.accountid;
END IF;
END
If I have completely misunderstood your issue, please update your question with the additional details mentioned above.

How to get the URL with the report parameters and values of the parameters of the executed report

Is it possible to get URL for a executed report (including selected parameter values) that can be emailed to colleagues? That they can follow the link to get the same as I, with the same selected parameters.
I found solution! It works with SSRS in SharePoint mode!!!
Report parameters and their values are stored in ReportingServiceTemDB in xml field of table. You can use the stored procedure to obtain and generate the URL (change or add stored procedure input parameters [SERVERNAME],[ReportingServiceDB], [ReportingServiceDBTempDB], [ReportLibraryName]).
Then create shared dataset and use dataset in reports with input parameters:
#parUserName = User!UserID;
#parReportName = Globals!ReportName
ALTER PROCEDURE [dbo].[p_guCreateUrlWithParameters]
#parUserName varchar(250),
#parReportName varchar(250),
#parTimeout int = 10
AS
/*
set #parUserName = 'REGION\11BelyaevDA'
set #parReportName = 'rptDITRequestTactical.rdl'
set #parTimeout = 120 //sec
*/
declare #results varchar(4000)
begin try
select
#results = coalesce(#results+'&rp:','') + url -- you have to change parameter prefix if you are using report server not in sharepoint mode
from
(
select
res.UserName,
res.Report,
res.CreationTime,
res.parName,
res.parType,
(case when res.parType = 'DateTime' then replace(convert(varchar,cast(res.parValue as date),103),'/','.') else res.parValue end) as parValue,
(res.parName+'='+(case when res.parType = 'DateTime' then replace(convert(varchar,cast(res.parValue as date),103),'/','.') else res.parValue end)) as url
from
(
select distinct
x.UserName,
x.Report,
x.CreationTime,
Paravalue.value('../../Name[1]', 'VARCHAR(250)') as parName,
Paravalue.value('../../Type[1]', 'VARCHAR(250)') as parType,
Paravalue.value('../../Prompt[1]', 'VARCHAR(250)') as parLable,
Paravalue.value('../../MultiValue[1]', 'VARCHAR(250)') as parMultiValue,
Paravalue.value('.[1]', 'VARCHAR(250)') as parValue
from
(
SELECT top 1
s.CreationTime
,s.SessionID
,u.[UserName]
,c.[name] [Report]
,d.[name] [DataSource]
,s.[ReportPath]
,convert(XML,s.[EffectiveParams]) as ParameterXML
,DATEDIFF(minute,s.[CreationTime],GETDATE()) [RunningTimeMinutes]
FROM [ServerName].[ReportingServiceDBTempDB].[dbo].[SessionData] as s with (NOLOCK)
JOIN [ServerName].[ReportingServiceDB].[dbo].[Catalog] as c with(NOLOCK)
ON RIGHT(c.Path, CHARINDEX('/', REVERSE(c.Path)) -1) = RIGHT(s.ReportPath, CHARINDEX('/', REVERSE(s.ReportPath)) -1) and c.Type = 2 -- if you are using report server not in sharepoint mode - use '\'
JOIN [ServerName].[ReportingServiceDB].[dbo].[DataSource] as d with(NOLOCK)
ON c.ItemID = d.ItemID
JOIN [ServerName].[ReportingServiceDB].[dbo].[Users] as u with(NOLOCK)
on u.UserId = s.ownerID and u.UserName = #parUserName
WHERE
RIGHT(c.Path, CHARINDEX('/', REVERSE(c.Path)) -1) = #parReportName -- if you are use report server not in sharepoint mode - use '\'
and datediff(ss,s.CreationTime, getdate()) < #parTimeout
order by s.Expiration desc
) as x
CROSS APPLY ParameterXML.nodes('//Parameters/Parameter/Values/Value') p ( Paravalue )
) res
) link
end try
begin catch
select isnull(#results,'')
end catch
set #results = 'http://[SERVERNAME]/_layouts/15/ReportServer/RSViewerPage.aspx?rv:RelativeReportUrl=/[ReportLibraryName]/'+#parReportName+'&rp:'+#results -- you have to change link if you are using eport server not in sharepoint mode
select isnull(#results,'')
GO
It most definitely is possible and I like to create mailto support links on reports that a user can click to send me (the guy that will be looking at their issue) an exact link to the report they use, complete with parameters.
Technet Page: Passing a Report Parameter Within a URL
Here is an example URL that we can break down:
http://server/reportserver?/Sales/Northwest/Employee Sales Report&rs:Command=Render&EmployeeID=1234
"http://" - obviously going to be the same for all links
"server" - the name of the ssrs server
"reportserver?" - the virtual directory where the report server's reports are accessed from:
You can find this by logging into the server and checking the Reporting Services Configuration Manager settings. The default value is "reportserver" if no one customized yours.
"/Sales/Northwest/Employee Sales Report/": The path to the report including the report name
"&rs:Command=Render": Just a command to the ssrs server to render the report
"&EmployeeID=1234": The parameter part you are interested in. EmployeeID in this case is the exact name of the parameter within your report (not the display name) and obviously 1234 is the value for the link.

How to optionally select multiple values for the same column in SQL?

So I am using Kentico CMS Desk 7 to generate reports for my company. In Kentico you create parameters and then create a table using sql and those parameters with the # symbol so whatever the user enters into that parameter, it will be the value of a parameter variable like #Status. I am wanting to add the ability for the user to either enter in one value, multiple values, or no values into the parameters, but I do not know how to implement the multiple values. I am a little new to SQL so bear with me. This is the SQL code I have right now:
select
ClaimNumber as 'Claim Number',
CustomerName as 'Customer Name',
DollarAmount as 'Dollar Amount',
[ReasonCode] as 'Reason code',
rt.[ReasonTypeName] as 'Reason type',
PlantNumber as 'Selling Company',
Status as 'Status'
from TABLE1 as c
join TABLE2 as u on u.UserID = c.DocumentCreatedByUserID
left join TABLE3 as rt on rt.ItemId = c.ReasonType
where ClaimDate between #FromDate and #ToDate
and ReasonCode like #ReasonCode
and ReasonType like #ReasonType
and (#SellingCompany = '' or PlantNumber = #SellingCompany)
and Status like #Status
order by ClaimNumber;
The parameter that I am trying to do this with is the selling company parameter denoted as #SellingCompany. Right now, this works for users not entering in any value and users entering in only one value, but I would like for users to have the ability to input multiple values separated by commas. I feel like an IN operator might work, but I am inexperienced in SQL and I don't know how I would implement this. I can't publish the data obviously because there is customer information, but this statement works as it is and I just need to know how to implement what I'm wanting to do. Thanks guys!
Have you tried this?
select
ClaimNumber as 'Claim Number',
CustomerName as 'Customer Name',
DollarAmount as 'Dollar Amount',
[ReasonCode] as 'Reason code',
rt.[ReasonTypeName] as 'Reason type',
PlantNumber as 'Selling Company',
Status as 'Status'
from TABLE1 as c
join TABLE2 as u on u.UserID = c.DocumentCreatedByUserID
left join TABLE3 as rt on rt.ItemId = c.ReasonType
where ClaimDate between #FromDate and #ToDate
and ReasonCode like #ReasonCode
and ReasonType like #ReasonType
and (#SellingCompany = '' or PlantNumber IN (#SellingCompany))
and Status like #Status
order by ClaimNumber;
I use this SQL function specifically when I need to cast a delimited string to a table value to use with the IN operator.
CREATE FUNCTION [dbo].[ParseIDListToTable]
(#vc_Ids nvarchar(MAX))
RETURNS #Id_table TABLE
(ID nvarchar(15))
BEGIN
DECLARE #in_Index1 AS INT, --Used to store ID delimiter(',') position in string
#vc_ID AS NVARCHAR(15)
/* initialize working variables */
SET #in_Index1 = CHARINDEX(',',#vc_Ids)
/* loop through ids in delimited string */
WHILE (#in_Index1 > 0 OR LEN(#vc_Ids) > 0)
BEGIN
/* parse out single id for processing */
IF #in_Index1 > 0
BEGIN
SET #vc_ID = Left(#vc_Ids,#in_Index1 - 1)
SET #vc_Ids = Right(#vc_Ids,Len(#vc_Ids) - #in_Index1)
END
ELSE
BEGIN
SET #vc_ID = #vc_Ids
SET #vc_Ids = ''
END
INSERT #Id_table (ID)
VALUES(#vc_ID)
/* prepare to loop */
SET #in_Index1 = CHARINDEX(',',#vc_Ids)
END
/* return the ids */
RETURN
END
Then I use it in my SELECT statement like so
WHERE PlantNumber IN (SELECT * FROM dbo.ParseIDListToTable('Microsoft,Apple,Dell'))
This should return the results you're looking for.

Update 500+ field records to include an increment value + attribute value

Im looking to update 500+ records in my mysql database so that the fields will be a value combination of an $incremental_value+db_user_first_name+#some_static_text. An example of the wished outcome:
1_firstname#staticstring.com, 2_george#staticstring.com, 3_johnny#staticstring.com etc.
I've been playing around with some approach as the following, but that naturally doesn't work (modified for hopefully better clarification).
UPDATE user
SET email = (($incremental_value+1)+(user.first_name))"#staticstring.com"
WHERE email = "empty#empty.com"
The correct syntax for string concatenation in MySQL is the concat() function:
UPDATE user cross join
(select #i = VALUETOSTART) var
SET email = concat(#i := #i + 1, '_', user.first_name, '#staticstring.com')
WHERE email = 'empty#empty.com';