How to get name of currently running tasks in ssis package - ssis

I have four tasks in sequence in a SSIS package. How to get name of currently running tasks after every 10 minutes?

Here is a script you can use to fetch running package_name with SQL Job agent. You could then make a ssis package to extract this data, and then set it up in an SQL JOB Agent which runs every 10 minutes. You can see the task name in message_source_name
Current running package with taskname:
USE SSISDB
GO
/*
Configuration
*/
-- Filter data by execution id (use NULL for no filter)
-- Show only Child Packages or everyhing
DECLARE #showOnlyChildPackages BIT = 0;
-- Show only message from a specific Message Source
DECLARE #messageSourceName NVARCHAR(MAX)= '%'
-- Filter data by project name (use % for no filter)
DECLARE #projectNamePattern NVARCHAR(100) = '%'
-- Filter data by package name (use % for no filter)
DECLARE #packageNamePattern NVARCHAR(100) = '%'
-- Filter data by execution id (use NULL for no filter)
DECLARE #executionIdFilter BIGINT = NULL;
with running as (
/*
Implementation
*/
-- Show last 15 executions
SELECT TOP 15
e.execution_id,
e.project_name,
e.package_name,
e.project_lsn,
e.status,
status_desc = CASE e.status
WHEN 1 THEN 'Created'
WHEN 2 THEN 'Running'
WHEN 3 THEN 'Cancelled'
WHEN 4 THEN 'Failed'
WHEN 5 THEN 'Pending'
WHEN 6 THEN 'Ended Unexpectedly'
WHEN 7 THEN 'Succeeded'
WHEN 8 THEN 'Stopping'
WHEN 9 THEN 'Completed'
END,
e.start_time,
e.end_time,
elapsed_time_min = datediff(mi, e.start_time, e.end_time)
FROM
catalog.executions e
WHERE
e.project_name LIKE #projectNamePattern
AND
e.package_name LIKE #packageNamePattern
AND
e.execution_id = ISNULL(#executionIdFilter, e.execution_id)
and e.status = 2
)
select * from running a
inner join
(
SELECT top 1 * FROM catalog.event_messages em
WHERE ((em.operation_id = #executionIdFilter) OR #executionIdFilter IS NULL)
--AND (em.event_name IN ('OnInformation', 'OnError', 'OnWarning'))
AND (package_path LIKE CASE WHEN #showOnlyChildPackages = 1 THEN '\Package' ELSE '%' END)
AND (em.message_source_name like #messageSourceName)
order by operation_id desc,message_time desc
)
b on a.execution_id = b.operation_id

Related

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.

Same Database, Same SQL Version, Very different Performance

We are having a performance issue with a reasonable simple stored procedure, so we to a back up of the database and restored it on a simple test machine and on our replica of our production environment. The only differences in the machines and the databases is the hardware, one is in a VM with 8Gig RAM and 4 processsors, the other is a physical cluster 64Gig RAM and 8 processors.
We have the same version of SQL Server (2014 SP1) on both machines, both databases restored from the same back up. When we run, the one takes less than a second, the other takes 2 minutes 40 seconds producing the same result set of 2976 rows.
The main table involved only has circa 59K rows. The execution plans are nearly identical but but for the outputs on one of the clustered index scans
So what is driving me nuts is how / why would an identical database on identical versions of SQL Server produce two wildly different actual number of rows (174822900 vs 58764) with 2975 executions vs 4 ??
This is the code being run
DBCC FREEPROCCACHE;
DECLARE #return_value int
EXEC #return_value = [dbo].[ngage_Tree_SelectClientData]
#ParentId = 0,
#FromDate = '2016-08-04 17:16:40.367',
#UserGroupId = '1|',
#MaxToReturn = 100000
SELECT 'Return Value' = #return_value;
and this is the code for the stored procedure iteself:
CREATE PROC dbo.ngage_Tree_SelectClientData
#ParentId BIGINT
,#FromDate DATETIME2
,#UserGroupId VARCHAR(50)
,#MaxToReturn INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #parentHierarchyId HIERARCHYID = (SELECT HierarchyId
FROM Tree
WHERE Id = #ParentId);
SELECT DISTINCT TOP (#MaxToReturn)
t.Id, t.ParentId,
t.Title, t.Ordinal, t.HelpTopicId,
t.IsFolder, t.SmallIcon, t.LargeIcon,
t.CmsTemplateId, t.IsSystemFolder,
t.ContextMenu, t.DateModified,
CASE
WHEN n2.[HierarchyId] IS NULL
THEN 0
ELSE 1
END AS 'HasChildren',
t.ToolTip,
t.[HierarchyId].ToString() AS ParentIds, t.Depth
FROM
Tree t
INNER JOIN
TreeToUserGroups ttug ON ttug.TreeId = t.Id
AND ttug.ReadPermission = 1
AND ttug.UserGroupId IN (SELECT ResultList
FROM dbo.SplitCommaList(#UserGroupId, '|'))
LEFT OUTER JOIN
Tree n2 ON t.[HierarchyId] = n2.[HierarchyId].GetAncestor(1)
WHERE
t.IsDeleted = 0
AND t.IsArchived = 0
AND t.DateModified > #FromDate
AND (#ParentId = 0
OR t.[HierarchyId].IsDescendantOf(#parentHierarchyId) = 1)
AND t.Id NOT IN (SELECT Id
FROM Tree
WHERE (TreeObjectType = N'EcomProduct'
AND Title = N'(MISC) MISC')
OR (Title = N'Tag Groups'
AND TreeObjectType = N'TagRoot')
)
ORDER BY
t.DateModified ASC;
END;
https://1drv.ms/u/s!Aj3dwBusMe7yqao2igQ-JZilD4fVzw DEV Plan XML
https://1drv.ms/u/s!Aj3dwBusMe7yqao1JWD-w8sOhvrFhw VM Plan XML

How to run concurring SQL query?

I am trying to run this sql query.
SELECT * FROM AverageFeedInfo WHERE No = (
SELECT No FROM UserResponse2 where Not Complain = '' )
When I run SELECT No FROM UserResponse2 where Not Complain = '' individually I have result 2 and 6, but if I run this
SELECT * FROM AverageFeedInfo WHERE No = (
SELECT No FROM UserResponse2 where Not Complain = '' )
I have only the result for 2 not for 6. Is it possible to get the answer for both 2 and 6. To be more clear is it possible to run the sql query like
SELECT * FROM AverageFeedInfo WHERE No = 2 or No = 6
Generally, when checking set membership in a SQL-based context use of an IN operator is more appropriate than =.

Calling stored procedure in MySQL takes forever to execute

I have a stored procedure which I'm trying to call, and it takes forever to execute. I have no idea what's wrong. A similar stored procedure in another database executes perfectly. I'm not well-versed with MySQL Workbench, so I don't know if the database settings are different or something.
Following is my stored procedure:
CREATE
DEFINER = `admin`#`%`
PROCEDURE `calculate_daily_coil_moved_by_crane_data`()
BEGIN
set #curr_date = curdate();
set #pre_date = date_add(curdate(), interval -1 day);
set #a_shift_start_ts = concat(#pre_date, ' 06:00:00');
set #a_shift_end_ts = concat(#pre_date, ' 13:59:59');
set #b_shift_start_ts = concat(#pre_date, ' 14:00:00');
set #b_shift_end_ts = concat(#pre_date, ' 21:59:59');
set #c_shift_start_ts = concat(#pre_date, ' 22:00:00');
set #c_shift_end_ts = concat(#curr_date, ' 05:59:59');
SELECT #curr_date,
#pre_date,
#a_shift_start_ts,
#a_shift_end_ts,
#b_shift_start_ts,
#b_shift_end_ts,
#c_shift_start_ts,
#c_shift_end_ts;
#SET DATA
insert into daily_coil_move_by_crane_data_for_report (crane_id, crane_name, date, a_shift, b_shift, c_shift)
select cr.id, cr.name, #pre_date, 0, 0, 0
from yms_phase3.crane cr
where active = 1
order by cr.name;
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE A Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'A';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set a_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #a_shift_start_ts and #a_shift_end_ts
group by in_data.crane_name), 0)
where (a_shift is null or a_shift = 0);
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE B Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'B';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set b_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #b_shift_start_ts and #b_shift_end_ts
group by in_data.crane_name), 0)
where (b_shift is null or b_shift = 0);
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE C Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'C';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set c_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #c_shift_start_ts and #c_shift_end_ts
group by in_data.crane_name), 0)
where (c_shift is null or c_shift = 0);
#----------------------------------------------------------------------------------------------------
#INSERT ALL CRANE ENTRY
insert into daily_coil_move_by_crane_data_for_report (crane_id, crane_name, date, a_shift, b_shift, c_shift)
select -1, 'ALL', #pre_date, SUM(a_shift), sum(b_shift), sum(c_shift)
from daily_coil_move_by_crane_data_for_report
where date = #pre_date
group by date;
#UPDATE TOTAL
update daily_coil_move_by_crane_data_for_report
set total_coils_moved = (a_shift + b_shift + c_shift)
where date = #pre_date;
END
Also tried to execute the query from Java using the following:
jdbcTemplate.execute("CALL calculate_daily_coil_moved_by_crane_data;");
But it gives me the following Exception:
java.sql.SQLException: Lock wait timeout exceeded
Any workaround I can do to solve this?
Please try and edit the configuration file, also search for the same here on stack. There are certain possibilities while checking this out,
Check and edit the config file on Hard drive for MySQL increase the cache capacity and default values as the default values are in KB's the memory allocated is very less and to execute such a big procedure it should at least be some MB.
Increase the connection String timeout, that is by setting up right time in seconds. by default it is 60 seconds, which is very less for executing such a procedure, I think in c# at least we set it to '0' seconds which means that it shall not get timed-out till the query is executed.
If Any left Joins/ inner query please try and check whether the same output is produced in inner joins ? as inner joins are faster than left or right joins.
Add Indexes, have foreign key references properly mapped for faster execution of query.
Hope it works.

SSIS job schedule

Lets say Job "Alphabet" does tasks A-Z. In 15min mark the job will be in task M or in other words it will not complete in 15 min. . During my tests, I ran without a schedule or a one time run, it runs and completes successfully. Then I ran with a scheduler with " Everyday: every 15m". Here with a scheduler, I see the job never hits Z or never completes. Is the SQL agent stopping the instance and starting a new one ?
This is an easy one to test for yourself. In the following, I create a SQL Agent Job with a single step which creates a table in tempdb if it doesn't exist.
It then waits 90 seconds before inserting the current timestamp. But, it is scheduled to run every minute.
USE [msdb]
GO
DECLARE #jobId binary(16)
EXEC msdb.dbo.sp_add_job
#job_name = N'Overlapping Execution'
, #enabled = 1
, #notify_level_eventlog = 0
, #notify_level_email = 2
, #notify_level_netsend = 2
, #notify_level_page = 2
, #delete_level = 0
, #category_name = N'[Uncategorized (Local)]'
, #job_id = #jobId OUTPUT
SELECT
#jobId
GO
EXEC msdb.dbo.sp_add_jobserver
#job_name = N'Overlapping Execution'
, #server_name = N'localhost\DEV2014'
GO
USE [msdb]
GO
EXEC msdb.dbo.sp_add_jobstep
#job_name = N'Overlapping Execution'
, #step_name = N'Insert into table'
, #step_id = 1
, #cmdexec_success_code = 0
, #on_success_action = 1
, #on_fail_action = 2
, #retry_attempts = 0
, #retry_interval = 0
, #os_run_priority = 0
, #subsystem = N'TSQL'
, #command = N'USE tempdb
GO
IF NOT EXISTS
(
SELECT * FROM sys.tables AS T WHERE T.name = ''WatchMe''
)
BEGIN
CREATE TABLE dbo.Watchme
(
StartTime datetime NOT NULL
);
END
GO
-- wait for 90 seconds to ensure overlap
WAITFOR DELAY ''00:01:30'';
-- Add a row so we can demonstrate activity
INSERT INTO
dbo.Watchme
(
StartTime
)
VALUES
(CURRENT_TIMESTAMP);
'
, #database_name = N'tempdb'
, #flags = 0
GO
USE [msdb]
GO
EXEC msdb.dbo.sp_update_job
#job_name = N'Overlapping Execution'
, #enabled = 1
, #start_step_id = 1
, #notify_level_eventlog = 0
, #notify_level_email = 2
, #notify_level_netsend = 2
, #notify_level_page = 2
, #delete_level = 0
, #description = N''
, #category_name = N'[Uncategorized (Local)]'
, #notify_email_operator_name = N''
, #notify_netsend_operator_name = N''
, #notify_page_operator_name = N''
GO
USE [msdb]
GO
DECLARE #schedule_id int
EXEC msdb.dbo.sp_add_jobschedule
#job_name = N'Overlapping Execution'
, #name = N'EveryMinute'
, #enabled = 1
, #freq_type = 4
, #freq_interval = 1
, #freq_subday_type = 4
, #freq_subday_interval = 1
, #freq_relative_interval = 0
, #freq_recurrence_factor = 1
, #active_start_date = 20141023
, #active_end_date = 99991231
, #active_start_time = 0
, #active_end_time = 235959
, #schedule_id = #schedule_id OUTPUT
SELECT
#schedule_id
GO
So, what happens? SQL Agent won't start the job if it's already running. If you try to manually run it
Start failed for Job 'Overlapping Execution'.
Request to run job Overlapping Execution (from User pity\dafool) refused because the job is already running from a request by User mr\T. (Microsoft SQL Server, Error: 22022)
Instead, the agent will skip the missed starts until it's able to actually start. Here you can see the history. It started at 4:50. Missed the start at 4:51 as it was already running but caught the 4:52 window.
If I query my watchme table
SELECT
WM.*
FROM
dbo.WatchMe AS WM
ORDER BY
1
I can see that yes, my insert times are approximately 90 seconds after the job would have started.
StartTime
2014-10-23 16:51:30.277
2014-10-23 16:53:30.767
2014-10-23 16:55:30.790
2014-10-23 16:57:30.793
2014-10-23 16:59:30.870
Directly answering the question
No, the Agent won't stop a currently executing job to start a new instance of it.
Turn on logging within your packages (I favor SQL Server and logging OnPre/PostExecute, OnError, OnTaskFailed) and you should be able to divine where it's at in the process along with any failure information.
Add a AA step where you check if the job is already running.
SELECT sj.name FROM msdb.dbo.sysjobactivity sja
INNER JOIN msdb.dbo.sysjobs sj ON sja.job_id = sj.job_id
WHERE sja.start_execution_date IS NOT NULL
AND sja.stop_execution_date IS NULL
AND name = 'Alphabet'
If so, skip steps A-Z.