How to get sysprocesses.program_name for current connection - sql-server

I need to retrieve the value of sysprocesses.program_name for the current connection. I use Sql Server 2008R2.
In other words i would like to join sysprocesses to this
select * from sys.dm_exec_connections
where session_id = ##SPID
But i am not succeeding.
Just to explain the context:
I need to know program_name of the current session because the application i am working on writes info about who is logged in into the system (it does not depend on sql serveer user, because sa is used for connection) into program_name (it is a trick).
If I could read program_name i would be able to implement some custom logic into a INSTEAD OF UPDATE trigger i am writing.
i am twaking a legacy application by working on triggers only (it is "emergency maintenance").

Use this builtin function:
select app_name()
Alternatively, you can use this query to get more than only the name of the program:
select *
from sys.[dm_exec_connections] as [dec]
inner join [sys].[sysprocesses] as [sp] on [dec].[session_id] = [sp].[spid]
where [dec].[session_id] = ##SPID

Ant_22: yes you can see Application Name if you add "Application Name" in connection string, exemple to see how many connections per process:
SELECT
DB_NAME(dbid) as DBName,
COUNT(dbid) as NumberOfConnections,
PROGRAM_NAME as ProgName,
loginame as LoginName
FROM
sys.sysprocesses
WHERE
dbid > 0
GROUP BY
dbid, PROGRAM_NAME, loginame

Related

Stop SQL Tracing

my MSSQL DB creates every second two SQL Server Profil - tace data file:
Screenshot
How can I stop that, because we don't want to tracing something and it files my memory?
My SELECT * FROM sys.traces is empty.
If I execute SELECT * FROM sys.server_event_sessions, the result looks like the following Screenshot:
Additionally, I execute the following command:
SELECT s.name, CAST(st.target_data AS XML).value('(/EventFileTarget/File/#name)[1]', 'NVARCHAR(100)')
FROM sys.dm_xe_sessions s
INNER JOIN sys.dm_xe_session_targets st ON s.address = st.event_session_address
WHERE target_name = 'event_file
The result looks like this:
Next, I open the system_health-file and get this displayed:
The hkenginexesession-file is empty.
Do you have enough permission to see trace list?
The visibility of the metadata in catalog views is limited to securable that a user either owns or on which the user has been granted some permission. For more information, see Metadata Visibility Configuration.
If the list is still empty with sysadmin premission then check if these files are created by Extended events:
USING SSMS:
Server > Management > Session
USING TSQL
SELECT s.name, CAST(st.target_data AS X`enter code here`ML).value('(/EventFileTarget/File/#name)[1]', 'NVARCHAR(100)')
FROM sys.dm_xe_sessions s
INNER JOIN sys.dm_xe_session_targets st ON s.address = st.event_session_address
WHERE target_name = 'event_file'
The above query return session name and filename of outputs.

Who (Or What) ran this query ID

I'd like to know who (Service account, user account ,etc ) ran each query_id that Query_Store records. Is there a way to do this? I've looked all over and can't seem to find anything.
Basically I'd like the data from this to be stored as well. Hostname, and Login Name are very useful to me.
SELECT sdest.DatabaseName
,sdes.session_id
,sdes.[host_name]
,sdes.[program_name]
,sdes.client_interface_name
,sdes.login_name
,sdes.login_time
,sdes.nt_domain
,sdes.nt_user_name
,sdec.client_net_address
,sdec.local_net_address
,sdest.ObjName
,sdest.Query
FROM sys.dm_exec_sessions AS sdes
INNER JOIN sys.dm_exec_connections AS sdec ON sdec.session_id = sdes.session_id
CROSS APPLY (
SELECT db_name(dbid) AS DatabaseName
,object_id(objectid) AS ObjName
,ISNULL((
SELECT TEXT AS [processing-instruction(definition)]
FROM sys.dm_exec_sql_text(sdec.most_recent_sql_handle)
FOR XML PATH('')
,TYPE
), '') AS Query
FROM sys.dm_exec_sql_text(sdec.most_recent_sql_handle)
) sdest
where sdes.session_id <> ##SPID
--and sdes.nt_user_name = '' -- Put the username here !
ORDER BY sdec.session_id
Credit: Execution datetime for SQL queries against SQL Server
There's no DMV that records which sessions ran which queries. To gather that information you must use an Extended Events trace, or a Database Audit.

SQL Server service takes more memory and how to find which user session/process is taking more memory?

SQL Server service in my environment takes more memory and I need to find which process takes more memory and wants to kill it. We tried to find using the below query but the value in SQL server service and value returned from the query is not matching.
SELECT spid,
RTRIM(status) AS Status,
SUSER_SNAME(sid) AS [User],
RTRIM(hostname) AS Host,
RTRIM(program_name) AS Program,
memusage * 8 AS memusage,
cpu,
physical_io,
blocked,
CASE WHEN sysprocesses.dbid = 0 THEN '-' ELSE DB_NAME(sysprocesses.dbid)END AS [Database],
cmd,
last_batch,
login_time,
net_library,
loginame,
h.text,
waittime,
lastwaittype,
waitresource
FROM master..sysprocesses
LEFT OUTER JOIN sys.dm_exec_connections dmexec ON dmexec.session_id = spid
OUTER APPLY sys.dm_exec_sql_text(dmexec.most_recent_sql_handle) h
WHERE hostname != '';

How can I get an accurate count of computers logged in to my SQL Server database?

We license our software by number of workstations.
I have a query that I have used for years to get an accurate count of the workstations logged in to my SQL Server database. For simplicity, all users use the same login name/password. This is built in to the script that attaches to the DB. They have access only to that DB with the exception of
USE [Master] GRANT VIEW SERVER STATE to MyUser
The query that has been working is below:
SELECT COUNT(Users) AS UserCount FROM (SELECT COUNT(Master.dbo.sysprocesses.hostname) AS Users FROM Master.dbo.sysprocesses LEFT OUTER JOIN Master.dbo.sysdatabases ON Master.dbo.sysdatabases.dbid = Master.dbo.sysprocesses.dbid WHERE (Master.dbo.sysdatabases.name = 'MyDatabase') GROUP BY Master.dbo.sysprocesses.net_address) AS UserCount_1
Basically this relies on the mac address (Master.dbo.sysprocesses.net_address), since both Workstation names and ip addresses can be duplicated.
Recently this has stopped working at a number of customers. Suddenly individual workstations are showing multiple net addresses for the same workstation causing a substantial overcount of users. This may be related to SQL Server 2012 - not sure.
What I need is a very reliable way to get a count of workstations logged in to my database.
If anyone can tell me why I am suddenly getting multiple net_addresses for each workstation and how to prevent that that would be one possible solution.
Otherwise if anyone can give me a rock solid way to get a workstation count other than the above that would be great. Our largest customer is 50 users by the way.
HERE IS AN EXAMPLE:
SELECT Master.dbo.sysprocesses.hostname AS Users, Master.dbo.sysprocesses.net_address FROM Master.dbo.sysprocesses
LEFT OUTER JOIN Master.dbo.sysdatabases ON Master.dbo.sysdatabases.dbid = Master.dbo.sysprocesses.dbid
WHERE Master.dbo.sysdatabases.name = 'mydb' GROUP BY Master.dbo.sysprocesses.hostname, Master.dbo.sysprocesses.net_address
RETURNS:
DAVID-PC 001CC490239E
FLOOR1 001CC41D8012
FLOOR2 CB8FEE6C5856
FLOOR3 A50B18FF1516
KER-PC7 6C626DEA68CC
LIZ-PC A4E553460E35
LIZ-PC EFE3F0E20260
LIZ-PC FD32F7B30360
PAP 9D35A704C29C
PAP CFB724BA1183
PAP D1A58A8878E6
PAP E9B116CA34B8
PAP F38B335A7AE6
Thanks in advance for any help.
You can get an accurate count of the users logged in to SQL Server database by the following query:
SELECT
DB_NAME(dbid) as DB
COUNT(dbid) as Numb
loginame as LoginNa
FROM
sys.sysprocesses
WHERE
dbid > 0
GROUP BY
dbid, loginame
Also you can get full details of connected users by this:
sp_who2 'Active'
Here is a way that will give you the number of IPs or MAC addresses connected to a given database. I'd go with IP as you might have multiple NICs/MACs in a given high end workstation.
SELECT COUNT(DISTINCT c.client_net_address) as DistinctIPCount,
COUNT(DISTINCT p.net_address) as DistinctMACCount
FROM sys.dm_exec_connections c INNER JOIN sys.dm_exec_sessions s ON c.session_id = s.session_id
INNER JOIN sysprocesses p ON s.session_id = p.spid
WHERE s.is_user_process = 1
AND p.dbid = DB_ID('yourdbnamehere')

List the queries running on SQL Server

Is there a way to list the queries that are currently running on MS SQL Server (either through the Enterprise Manager or SQL) and/or who's connected?
I think I've got a very long running query is being execute on one of my database servers and I'd like to track it down and stop it (or the person who keeps starting it).
This will show you the longest running SPIDs on a SQL 2000 or SQL 2005 server:
select
P.spid
, right(convert(varchar,
dateadd(ms, datediff(ms, P.last_batch, getdate()), '1900-01-01'),
121), 12) as 'batch_duration'
, P.program_name
, P.hostname
, P.loginame
from master.dbo.sysprocesses P
where P.spid > 50
and P.status not in ('background', 'sleeping')
and P.cmd not in ('AWAITING COMMAND'
,'MIRROR HANDLER'
,'LAZY WRITER'
,'CHECKPOINT SLEEP'
,'RA MANAGER')
order by batch_duration desc
If you need to see the SQL running for a given spid from the results, use something like this:
declare
#spid int
, #stmt_start int
, #stmt_end int
, #sql_handle binary(20)
set #spid = XXX -- Fill this in
select top 1
#sql_handle = sql_handle
, #stmt_start = case stmt_start when 0 then 0 else stmt_start / 2 end
, #stmt_end = case stmt_end when -1 then -1 else stmt_end / 2 end
from sys.sysprocesses
where spid = #spid
order by ecid
SELECT
SUBSTRING( text,
COALESCE(NULLIF(#stmt_start, 0), 1),
CASE #stmt_end
WHEN -1
THEN DATALENGTH(text)
ELSE
(#stmt_end - #stmt_start)
END
)
FROM ::fn_get_sql(#sql_handle)
If you're running SQL Server 2005 or 2008, you could use the DMV's to find this...
SELECT *
FROM sys.dm_exec_requests
CROSS APPLY sys.dm_exec_sql_text(sql_handle)
More about sys.dm_exec_requests
More about sys.dm_exec_sql_text
You can run the sp_who command to get a list of all the current users, sessions and processes. You can then run the KILL command on any spid that is blocking others.
I would suggest querying the sys views. something similar to
SELECT *
FROM
sys.dm_exec_sessions s
LEFT JOIN sys.dm_exec_connections c
ON s.session_id = c.session_id
LEFT JOIN sys.dm_db_task_space_usage tsu
ON tsu.session_id = s.session_id
LEFT JOIN sys.dm_os_tasks t
ON t.session_id = tsu.session_id
AND t.request_id = tsu.request_id
LEFT JOIN sys.dm_exec_requests r
ON r.session_id = tsu.session_id
AND r.request_id = tsu.request_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) TSQL
This way you can get a TotalPagesAllocated which can help you figure out the spid that is taking all the server resources. There has lots of times when I can't even bring up activity monitor and use these sys views to see what's going on.
I would recommend you reading the following article. I got this reference from here.
As a note, the SQL Server Activity Monitor for SQL Server 2008 can be found by right clicking your current server and going to "Activity Monitor" in the context menu. I found this was easiest way to kill processes if you are using the SQL Server Management Studio.
There are various management views built into the product. On SQL 2000 you'd use sysprocesses. On SQL 2K5 there are more views like sys.dm_exec_connections, sys.dm_exec_sessions and sys.dm_exec_requests.
There are also procedures like sp_who that leverage these views. In 2K5 Management Studio you also get Activity Monitor.
And last but not least there are community contributed scripts like the Who Is Active by Adam Machanic.
SELECT
p.spid, p.status, p.hostname, p.loginame, p.cpu, r.start_time, r.command,
p.program_name, text
FROM
sys.dm_exec_requests AS r,
master.dbo.sysprocesses AS p
CROSS APPLY sys.dm_exec_sql_text(p.sql_handle)
WHERE
p.status NOT IN ('sleeping', 'background')
AND r.session_id = p.spid
Actually, running EXEC sp_who2 in Query Analyzer / Management Studio gives more info than sp_who.
Beyond that you could set up SQL Profiler to watch all of the in and out traffic to the server. Profiler also let you narrow down exactly what you are watching for.
For SQL Server 2008:
START - All Programs - Microsoft SQL Server 2008 - Performance Tools - SQL Server Profiler
Keep in mind that the profiler is truly a logging and watching app. It will continue to log and watch as long as it is running. It could fill up text files or databases or hard drives, so be careful what you have it watch and for how long.
In the Object Explorer, drill-down to: Server -> Management -> Activity Monitor. This will allow you to see all connections on to the current server.
You can use below query to find running last request:
SELECT
der.session_id
,est.TEXT AS QueryText
,der.status
,der.blocking_session_id
,der.cpu_time
,der.total_elapsed_time
FROM sys.dm_exec_requests AS der
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS est
Using below script you can also find number of connection per database:
SELECT
DB_NAME(DBID) AS DataBaseName
,COUNT(DBID) AS NumberOfConnections
,LogiName
FROM sys.sysprocesses
WHERE DBID > 0
GROUP BY DBID, LogiName
For more details please visit:
http://www.dbrnd.com/2015/06/script-to-find-running-process-session-logged-user-in-sql-server/
here is a query that will show any queries that are blocking. I am not entirely sure if it will just show slow queries:
SELECT p.spid
,convert(char(12), d.name) db_name
, program_name
, convert(char(12), l.name) login_name
, convert(char(12), hostname) hostname
, cmd
, p.status
, p.blocked
, login_time
, last_batch
, p.spid
FROM master..sysprocesses p
JOIN master..sysdatabases d ON p.dbid = d.dbid
JOIN master..syslogins l ON p.sid = l.sid
WHERE p.blocked = 0
AND EXISTS ( SELECT 1
FROM master..sysprocesses p2
WHERE p2.blocked = p.spid )
The right script would be like this:
select
p.spid, p.status,p.hostname,p.loginame,p.cpu,r.start_time, t.text
from sys.dm_exec_requests as r, sys.sysprocesses p
cross apply sys.dm_exec_sql_text(p.sql_handle) t
where p.status not in ('sleeping', 'background')
and r.session_id=p.spid
SELECT
p.spid, p.status, p.hostname, p.loginame, p.cpu, r.start_time, t.text
FROM
sys.dm_exec_requests as r,
master.dbo.sysprocesses as p
CROSS APPLY sys.dm_exec_sql_text(p.sql_handle) t
WHERE
p.status NOT IN ('sleeping', 'background')
AND r.session_id = p.spid
And
KILL #spid
in 2005 you can right click on a database, go to reports and there's a whole list of reports on transitions and locks etc...
Trying to put things together (hope to be helpful):
SELECT
p.spid,
RIGHT(CONVERT(varchar, DATEADD(ms, DATEDIFF(ms, p.last_batch, GETDATE()), '1900-01-01'), 121), 12) AS [batch_duration],
p.[program_name],
p.hostname,
MAX(p.loginame) AS loginame,
(SELECT SUBSTRING(text, COALESCE(NULLIF(spid.stmt_start, 0), 1) + 1, CASE spid.stmt_end WHEN -1 THEN DATALENGTH(text) ELSE (spid.stmt_end - spid.stmt_start) END) FROM ::fn_get_sql(spid.[sql_handle])) AS [sql]
FROM
master.dbo.sysprocesses p
LEFT JOIN (
SELECT
ROW_NUMBER() OVER(PARTITION BY spid ORDER BY ecid) AS i,
spid,
[sql_handle],
CASE stmt_start WHEN 0 THEN 0 ELSE stmt_start / 2 END AS stmt_start,
CASE stmt_end WHEN -1 THEN -1 ELSE stmt_end / 2 END AS stmt_end
FROM sys.sysprocesses
) spid ON p.spid = spid.spid AND spid.i = 1
WHERE
p.spid > 50
AND p.status NOT IN ('background', 'sleeping')
AND p.cmd NOT IN ('AWAITING COMMAND', 'MIRROR HANDLER', 'LAZY WRITER', 'CHECKPOINT SLEEP', 'RA MANAGER')
GROUP BY
p.spid,
p.last_batch,
p.[program_name],
p.hostname,
spid.stmt_start,
spid.stmt_end,
spid.[sql_handle]
ORDER BY
batch_duration DESC,
p.spid
;
Use Sql Server Profiler (tools menu) to monitor executing queries and use activity monitor in Management studio to see how is connected and if their connection is blocking other connections.
You should try very usefull procedure sp_whoIsActive which can be found here: http://whoisactive.com and it is free.

Resources