SQL Server logs location - sql-server

How can I retrieve all T-SQL statements fired by users in last one month in SQL Server database?
I have looked at sys tables but I am not able to figure out where the logs are stored.

In SQL Server we don't keep track of users who execute queries, except for some DML/DDL captured by the default trace or run SQL Profiler
Better to create a server side trace or enable SQL Audit to track down activity from users that you want to track or you don't trust.
If you are using any DMV for capture data, remember that DMV data gets reset if the DMV is cleared out, sql server is restarted, etc.
SQL query:
USE master
go
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
Query Store (SQL Server 2016+) instead of the DMV's. This gives better ability to look into historical data, as well as faster lookups and very efficient to capture short-running queries that can't be captured by sp_who/sp_whoisactive as well.

Related

How to retrieve the list of updated database objects/tables ordering by recent time?

I am working with a database named "MM" which has several tables.From frontend I saved some data and it successful, now I want to check the table modified/altered behind the scene as I am unaware of the RDBMS, what will be the query to check the last updated/altered table?
N.B: This is SQL Server 2008
Try with this query it should help you:
SELECT OBJECT_NAME(OBJECT_ID) AS TableName,
last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID( 'MM')

Tracking deletes on SQL Server

I intend to track delete actions done on a SQL Server DB whose recovery model is simple.
Do such actions get logged when the DB is in this mode?
You can achieve your goal in many different way. If you want you can read delete operations from sql server transaction log, but you will "loose" it after each transaction log backup if you are in full recovery model. In simple recovery model you can not control the transaction log contents.
To find delete operations for a particular table you can use the following query:
DECLARE #MonitoredTable sysname
SET #MonitoredTable = 'YouTable'
SELECT
u.[name] AS UserName
, l.[Begin Time] AS TransactionStartTime
FROM
fn_dblog(NULL, NULL) l
INNER JOIN
(
SELECT
[Transaction ID]
FROM
fn_dblog(NULL, NULL)
WHERE
AllocUnitName LIKE #MonitoredTable + '%'
AND
Operation = 'LOP_DELETE_ROWS'
) deletes
ON deletes.[Transaction ID] = l.[Transaction ID]
INNER JOIN
sysusers u
ON u.[sid] = l.[Transaction SID]
Another approach you can use is to write an "audit trigger" or you can use directly sql server auditing features/Sql server extended events as well explained in this Apex webpage:
SQL Server database auditing techniques

SQL Server Management Studio - history of commands run

I have previously altered a table, added a column and modify a stored procedure.
I do not remember exactly which table and which stored procedure,
is there some log in sql management studio about what changes were done in a particular DB?
I have tried what is described here How to see query history in SQL Server Management Studio but i have not found the changes made to the DB
There's a few ways that you can get this information. Firstly you could try the standard reports --> Schema Changes History.
The information for this comes from:
SELECT cat.name AS Category
, b.name AS EventCaptured
, c.name AS ColumnCaptured
FROM fn_trace_geteventinfo(1) AS a
INNER JOIN sys.trace_events AS b
ON a.eventid = b.trace_event_id
INNER JOIN sys.trace_columns AS c
ON a.columnid = c.trace_column_id
INNER JOIN sys.trace_categories AS cat
ON b.category_id = cat.category_id
ORDER BY Category, EventCaptured, ColumnCaptured
Alternatively, query sys.traces to find the location of the default trace and feed this into fn_trace_gettable as per below.
SELECT *
FROM fn_trace_gettable
('C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\LOG\log.trc', default)
You can use Security\Server Audit Specification and enable DATABASE_OBJECT_CHANGE_GROUP audit on your database.
Use following reference in order to use SQL Server server audit.
CREATE SERVER AUDIT SPECIFICATION (Transact-SQL)
Create a Server Audit and Server Audit Specification
You can use the modify_date column in sys.objects table
SELECT *
FROM SYS.OBJECTS
WHERE Modify_Date BETWEEN <date_of_modification> AND <date_of_modification> + 1
and then you can try to narrow it down.
You can be even more specific and run the query for just tables and stored procedures.
SELECT *
FROM SYS.objects
WHERE TYPE IN ('IT', 'S', 'U', 'P', 'PC', 'X')
AND modify_date BETWEEN '10-Jun-2014' AND '11-Jun-2014'
I develop SSMSBoost add-in for SSMS and we have "Executed Query history" there. All actions are logged with timestamp, connection information and execution result. This will certainly only work, if you do all changes from SSMS with SSMSBoost installed. If someone will perform changes from other machine you will not see them, until he uses SSMSBoost as well and you share execution history.

Why are these DMVs returning rows for all databases except one?

I am trying to query the DMVs in SQL Server 2008 R2.
On this server are two user databases called histrx and OpenLink. To prove I have their names correct:
select db_id('histrx') -- Returns 5
select db_id('OpenLink') -- Returns 7
If I run the following query, picking out entries for the histrx database, I get 25 rows in the result set:
select top 25
total_worker_time/execution_count as avg_worker_time,
total_logical_reads/execution_count as avg_logical_reads,
db_name(s.dbid) as [db_name],
object_name(s.objectid, s.dbid) as [object_name],
execution_count,
plan_generation_num,
last_execution_time,
creation_time,
[text],
p.query_plan
from
sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.plan_handle) s
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) p
where
db_name(s.dbid) = 'histrx'
order by
avg_logical_reads desc
If I then change the where clause to the following, no rows are returned:
where
db_name(s.dbid) = 'OpenLink'
I know that there is a significant amount of activity on the OpenLink database. If I look at Recent Expensive Queries in the Activity Monitor, I can see entries for OpenLink, and I'm pretty sure this is using the DMVs underneath.
I'm running the Activity Monitor and the DMV query under the same
login
That login is the owner of the OpenLink database
If I run select * from fn_my_permissions (NULL, 'server'); then I can see I have VIEW SERVER STATE permissions
If I remove the where clause, I see entries for other databases such as msdb and distribution
Here is a screenshot of the mappings for my login. I'm pretty sure I shouldn't be the owner, but that's a different question.
Can anyone tell me why my DMV query is returning zero rows for this database?
Quote from Books Online 2008 R2 > sys.dm_exec_sql_text:
dbid smallint ID of database. Is NULL for ad hoc and prepared SQL
statements.
1) So, for this type of SQL statements, where db_name(s.dbid) = 'OpenLink' means where NULL = 'OpenLink' and this predicate is evaluated to UNKNOWN.
2) dbid column is NOT NULL for "non-adhoc and non-prepared SQL" statements (ex. for stored procedures).
3) For SQL 2008R2 you might get the dbid for "ad hoc and prepared SQL statements" from sys.dm_exec_plan_attributes ( plan_handle ) function (link) using this query:
SELECT
...
ISNULL(src.dbid,CONVERT(SMALLINT,att.value)) AS my_dbid,
DB_NAME(ISNULL(src.dbid,CONVERT(SMALLINT,att.value))) my_dbname,
...
FROM
sys.dm_exec_query_stats qs
...
CROSS APPLY sys.dm_exec_plan_attributes(qs.plan_handle) att
WHERE att.attribute='dbid'

Sql Server - how to get last server restart (DMV reset date/time)

I'm using some modifications to Glenn Berry's excellent DMV queries!
However, I would like to add to the resultset the 'last server restart', or to be more specific, the date/time the statistics for (all, the specific) DMV was reset.
Since it would be quite important to know last reset when looking at the statistics, I want to make absolutely sure the date/time is accurate and shown.
Question: How can you get the most accurate date/time of when a/all DMV statistic was reset?
Thanks!
-D
SELECT sqlserver_start_time FROM sys.dm_os_sys_info
Using a prior question (different key words), I ended up using this approach. As always, up to the individual what would be 'best' for them!
SELECT create_date
FROM sys.databases
WHERE name = 'tempdb'
source: Find out how long the sql server service has been running, from t-sql
This will work but you have to know the service name also its only available with R2 and later
SELECT last_startup_time
FROM sys.dm_server_services
WHERE servicename = "Your Service name"
Although this won't be totally accurate since you can also reset the DB specific views via a DB detach or a DB close.
Also there are two views that can be reset on a live db sys.dm_os_latch_stats and sys.dm_os_wait_stats
There are many ways to check when was SQL server restarted last time.
Below mentioned SQL queries can be used to quickly find out the
server restart date time.
SELECT sqlserver_start_time FROM sys.dm_os_sys_info;
SELECT login_time FROM sys.dm_exec_sessions WHERE session_id = 1;
select start_time from sys.traces where is_default = 1 ;
SELECT crdate FROM sysdatabases WHERE name='tempdb' ;
SELECT create_date FROM sys.databases WHERE name = 'tempdb' ;
There are various way to find out SQL Server reboot time. Following are the codes which return the server re-boot date:
SELECT sqlserver_start_time FROM sys.dm_os_sys_info;
SELECT login_time FROM sys.dm_exec_sessions WHERE session_id = 1;
SELECT start_time from sys.traces where is_default = 1;
SELECT crdate FROM sysdatabases WHERE name='tempdb';
SELECT create_date FROM sys.databases WHERE name = 'tempdb';

Resources