Thursday, September 27, 2018

Currently running queries

Here is a piece of code that shows information about SQL queries running on the instance. I removed system queries from that selection.
Usually, I put that in a view... This is very usefull to understand what is running on your SQL Server instance when you see slowness, out-of-memory, etc...
SELECT
 r.start_time AS StartDate,
 DATEDIFF(SECOND, r.start_time, GETDATE()) AS DurationInSecond,
 r.session_ID AS [SPID],
 USER_NAME(r.user_id) AS UserName,
 DB_NAME(r.database_id) AS [Database],
 SUBSTRING(t.text,
  ( r.statement_start_offset / 2 ) + 1,
  CASE WHEN statement_end_offset = -1 OR statement_end_offset = 0
  THEN ( DATALENGTH(t.Text) - r.statement_start_offset / 2) + 1
  ELSE ( r.statement_end_offset - r.statement_start_offset ) / 2 + 1
  END) AS SqlQuery, 
 t.text AS SqlFullQuery,
 r.Status AS QueryStatus,
 r.command AS SqlCommand,
 r.wait_type AS WaitType,
 r.wait_time AS WaitTime,
 wait_resource AS WaitResource,
 r.blocking_session_id AS BlockingSessionId,
 r.cpu_time / 1000 AS CpuInSecond,
 r.logical_reads AS ReadLogical,
 (r.logical_reads * 8 / 1024) AS ReadLogicalInMB,
 r.reads AS ReadPhysical,
 (r.reads * 8 / 1024) AS ReadPhysicalInMB,
 r.writes AS WritePhysical,
 (r.writes * 8 / 1024) AS WritePhysicalInMB,
 ISNULL(NULLIF(CASE
  WHEN s.nt_domain IS NULL THEN ''
  ELSE s.nt_domain + '\' END + s.nt_user_name,
  ''), s.login_name) AS NtUserName,
 s.memory_usage AS SessionMemoryUsage,
 q.query_plan AS QueryPlan,
 s.program_name AS ProgramName,
 s.host_name AS HostName,
 s.client_interface_name AS ClientInterfaceName,
 r.sql_handle AS SqlHandle,
 r.session_id AS SessionId
FROM master.sys.dm_exec_requests r WITH (NOLOCK)
OUTER APPLY master.sys.dm_exec_sql_text(r.sql_handle) t
OUTER APPLY master.sys.dm_exec_query_plan(r.plan_handle) q
LEFT JOIN master.sys.dm_exec_sessions s WITH (NOLOCK) ON s.session_id = r.session_id
WHERE s.login_name <> 'sa'
AND r.session_id > 50

Wednesday, September 26, 2018

Check whether user running Sql Server engine has enough privileges

SQL Server installation automatically grants privileges to the user that runs MSSQL engine.
But, if you change the user that runs the engine AFTER the installation is complete, these permissions are not applied automatically. So it is important to remember to set these privileges.
Here is a script that helps you to determine which privileges you need to give. Depending of your SQL Server configuration, some may not be needed.
DECLARE @Res TABLE ( [output] NVARCHAR(255) );

INSERT INTO @Res
EXEC xp_cmdshell 'WHOAMI';
SELECT 'MSSQL engine runs with user ' + output
FROM @Res
WHERE output IS NOT NULL

DELETE FROM @Res
INSERT INTO @Res
EXEC xp_cmdshell 'WHOAMI /PRIV';

SELECT
 rp.PrivilegeName,
 RTRIM(LTRIM(REPLACE(r.output, rp.PrivilegeName, ''))) AS PrivilegeStatus
FROM @Res r
INNER JOIN
(
 VALUES
 ( 'SeAssignPrimaryTokenPrivilege' ),
 ( 'SeChangeNotifyPrivilege' ),
 ( 'SeIncreaseQuotaPrivilege' ),
 ( 'SeLockMemoryPrivilege' )
) rp ( PrivilegeName ) ON r.output LIKE '%' + rp.PrivilegeName + '%'
To add these privileges, go to Server Manager / Tools / Local Security Policy (or run secpol.msc).
Under Security Settings / Local Policies / User Rights Assignment, you can find the privileges mentioned above. Open each one that is disabled, and add the MSSQL engine user.
A reboot of server may be required for changes to take effect.

Resources: