Is there a way to monitor which data items are queried in SQL Server? [migrated] - sql-server

This question was migrated from Stack Overflow because it can be answered on Database Administrators Stack Exchange.
Migrated 19 days ago.
I am working on a largish SQL Server database and we have Extended Events logging switched on.
One of the main tables has a column called DataItem which contains a relatively small (<100) number of values across the millions of records.
The client would like a report showing who has accessed each DataItem, when it was accessed, and with which technology.
Is there any SQL Server function or other software that can provide this?
Extended events gives the who, when and how but not the what.

You can use an AUDIT for this.
https://learn.microsoft.com/en-us/sql/relational-databases/security/auditing/sql-server-audit-database-engine?view=sql-server-ver16
Here you can add the name and location and how large the file can grow.
Enable it.
In the database you would like to audit, add the database audit.
Enter your Autit Action Type, in this case SELECT, but perhaps you would also like to see the UPDATE, INSERT and DELETE actions?
Don't forget to enable it:
After running some selects, you can see the audit information:

Related

Retrospective Tracking of Manual Table Editing in SQL Server

Is there anyway to retrospectively determine if a table (or rows/fields) have been manually edited in SQL Server 2016.
Yup, you read that right. I'm trying to unravel some inconsistent data on a production database. Based on my interactions with the user and analysis of the table in question (sequential IDs don't make sense, LastUpdateDate fields inconsistent, etc.), I suspect that the table was manually edited.
Yup, it's the production database.
I appreciate that I won't be able to get what fields have changed but if I can show that the user HAS manually edited the table/database, we can work to resolve the situation.

Is this an appropriate database design if I wanted to audit my table?

It's my first time creating an audit log for a PoS WPF application and was wondering on how exactly do I implement an auditing system because it seems like each option available has its ups and downs. So far from reading numerous articles/threads, I've narrowed down a few common practices on audit logs:
1. Triggers - Unfortunately, due to the nature of my app, I can't make use of triggers as it has no way of knowing which user has done the action. So what I did instead was to create a Stored Procedure which will handle the customer insert along with the customer log insert and its details. The Customer_Id will be provided by the application when using the Stored Procedure.
2. Have an old and new value - My initial plan was to only include the latter since I can reference its old value with the new value from the row before it but storing the the old and new value seemed more sensible, complexity-wise.
3. Use a separate database for the log / 4. Foreign Keys - This is probably my main concern, if I decide to use a separate database for the audit table, then I couldn't setup foreign keys for the customer and employee involved.
I created a mock-up erd with a master-detail table result to be shown on the wpf app to display the log to an admin and would really like your thoughts on possible problems that may arise (There's also an employee table but I forgot to put it):
https://ibb.co/dheaNK
Here's a few info that might be of help:
The database will reside together with the wpf app, which is a single computer.
The amount of customers will be less than 1000.
The amount of regular employees will be 3.
The amount of admins will be 2.
You can enable CDC Change Data Capture on SQL Server database for a specific table
This will enable you to collect all data changes on the database table logged in special tables.
You can also refer to official documents too
Here is a list of DML commands and how data changes are logged in the CDC table created for the source database table
What is good about CDC is it comes default with SQL Server and you don't have to do anything for logging. The only requirement is SQL Server Agent should be running so that the changes can be reflected on log table.

Security Audit (CRUD) - Microsoft Access

My client has been using Microsoft Access 2010 for quite a while and they received some Security Audit Requirements. They are using a Linked Tables approach connecting to Microsoft SQL Server 2012 Express.
The requirements states that all actions against the data must be logged. (INSERT, UPDATE, DELETE AND SELECT statements)
For the INSERT, UPDATE, DELETE statements I could create a trigger which would log the changes.
The issue is around the audit of SELECT statements. If the data was read-only, I could have used a Stored Procedure which would have logged the query. But executing a Stored Proc makes a Recordset not updatable.
Does anyone have an idea how to approach this challenge?
I'm open to a lot of strategies... (Connecting Access to SQL through a web service, anything...)
It's important to note that my client does not have $30k to spend on an Enterprise edition of SQL Sever as they are a small-business with less than 10 employees.
SELECT statements are part of the database-level audit action groups in SQL Server. (Search that page for "database-level audit actions".) But that level of auditing requires SQL Server Enterprise edition.
Theoretically, you can limit all access to use only stored procedures regardless of whether the data is read-only. Write the stored procedure to write auditing information to the log first, then do whatever else needs to be done--SELECT, INSERT, etc.
Practically, you might not be able to do that. It depends on the applications that hit your database. Limiting all access to use only stored procedures can break applications that expect other things. (How would a Ruby on Rails application respond if you switched to just stored procedures?)
A bulletproof audit system that makes your database unusable isn't very good; it's simpler and cheaper to just shut down the database server altogether.
You could upgrade to a SQL Server edition that supports SQL Server profiler.
The other option is to get other tools to audit like sql audit for example.
You could turn on JET showplan. This would log all queries used by Access.
http://www.techrepublic.com/article/use-microsoft-jets-showplan-to-write-more-efficient-queries/?siu-container
As I pointed out in comments you really fooling the audit requirements UNLESS each form is opened using a where clause that limits the viewing of data in that form to the ONE record. If you don’t do this, then a form opened to a linked table could have 1000’s of records, and user(s) hitting ctrl-f to find and jump to one record means the SELECT statement tells you ZERO about what the user actually looked at. So while you can turn on show plan, the audit concept would not tell you anything about what the user actually looked at unless application design changes are made to restrict forms to one record. And to be fair, 99% of my applications in fact do open and restrict the main editing form to the one record via a where clause.
So while you can technology wise log all SELECT commands as per above, it not really in the sprit of such a log since such a log would not be of any use to determine what actual records the user looked at.

Locking tables in a backend access database using vb.net 2010

My problem is that I need to use a access database as a backend for my visual basic.net program.
The database will be accessed by a maximum of 10 users but I want to lock tables when a user is updating a record.
I am unable to use the SQL server at the company due to it storing sensitive information.
I have some basic knowledge of ado.net
I have read many articles but I can't find any articles that say how to lock a access .mdb file using Visual basic.net
I am aware that a SQL server is a better option but this is not possible option for me at the moment
I suspect that your best bet is to add a "Locks" table which contains a record for each table in your database and a flag that indicates if the table is locked or not.
The calling methods would be responsible for checking this table prior to executing their code.
Because you will be working with individual records, the Access record locking mechanism should prevent simultaneous updates of a single record in this table, but if you get a lock, you should probably double-check it after obtaining it to ensure that it is valid.

What sort of audit information is stored by sql server when a CREATE TABLE or ALTER TABLE operation is performed?

The inspiration for this question is a stored proc broke on me because it called another stored proc that inserted data in a table whose schema was completely altered.
The question is you have a table in a SQL Server database, and you don't know how it got there. You don't have any DDL triggers in place for custom audit information, and there is no record in your source control repository of the tables DDL. Using only SQL Server, what forensic data can you obtain about the table.
Myself, and whoever stumbles across this question in a similar situation, is not going to be helped by suggestions regarding version control and DDL triggers. Those are great go forward solutions, and there is plenty of info on this blog about those topics, if corporate politics allows us to implement those solutions. What I, and people in my situation really need is to be able to gather as many fragments of data as possible from SQL server, to combine with whatever other data we can come up with.
Unfortunately, you have no way to reconstruct what happened, except:
if the DBAs have traces running and the history. SQL Server 2005 has a default trace and there is the "blackbox" trace, but these are used to find out what happened right before a crash
if you have FULL recovery model, then you can try a log viewer tool (free Red Gate one)
depending on activity and your security model, you could also check the Windows Security Log to see who logged in with DDL privileges
the SQL event logs may also have information. For example, if you have enabled the trace flag that logs "permission" errors, then you can see when it started. Or the person who made the change may have generated other exceptions that are logged
you could ask those with rights. It could be a genuine mistake (eg thought they were in dev)
The following query got me the create and last modify time.
SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbTableInQuestion]') AND type in (N'U')
You should be able to find the creation of the table in the transaction log. I have never used any of the viewer tools here, and I couldn't tell you how to search back in time for this, but everything happens in a transaction, so it's gotta be logged -- even the system tables...

Resources