How to audit SQL Server 2008 queries through WCF Services? - sql-server

I want to save any kind of log/tables with every query executed by my application.
I know I could do this by coding it (before I make any query, I insert a new row in a log table with the query and the user who is executing it.
I have read it can be done automatically but I'm not sure how can it work with WCF Services. I mean every query is going to be executed by the same SQL user and this wouldn't be very useful for audit operations (I need to know WHO made every query, and users will be validated against my own users tables).
Have you ever had a similar scenario? Thanks in advance!

As a starting point it may be worth looking into doing this via SQL Server Profiler. You can normally find this in the Tools Menu in Management Studio.
You can set up a trace to capture all SQL run on a server. More importantly you have a myriad of filter options which can be applied so that you only capture the data you are interested in (e.g. DatabaseName, UserName).
This information can be stored directly in a SQL Table, which should give you the abillity to join onto. Of course running anything like this will result in some overhead on the SQL box.

You can try the SQL Server Audit feature. It audits singe or groups of events both on server and database level. However, be advised that the database level auditing is available in SQL Server Enterprise and Developer editions only

Related

Automate sql server profiler to record data then save data to a table continuously

Is there a way to automate sql server profiler to record data then save data to a table continuously?
The reason, I am supporting a fragile SQL Server application and there is no auditing. I receive a lot of support calls regarding the deletion of records. I want a quick way to be able to view who has changed what data.
You can configure your profiler to save the trace directly to table as described here: How To Save a SQL Server Trace Data to a Table
But it's not a good idea for 2 reasons: first, profiler itself will be loading up your server, second, writing to table is the most costly option and you can even loose some events.
Maybe if you are on Enterprise edition you can use SQL Server database audit
that is more light weight
And here you can find a complete example of setting up database audit that audits the DELETE events
Here are few articles for your reference.
Save trace results to a database table
https://learn.microsoft.com/en-us/sql/tools/sql-server-profiler/save-trace-results-to-a-table-sql-server-profiler
Save Trace Results to a Table
https://technet.microsoft.com/en-us/library/ms191276(v=sql.110).aspx
9 Steps to an Automated Trace
http://sqlmag.com/t-sql/9-steps-automated-trace
alternatively, you may try this automated solution ( https://www.lepide.com/lepideauditor/sql-server-auditing.html ) to accomplish this task.

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.

Copy access database to SQL server periodically

I have an access 2003 database that holds all of my business data. This access database gets updated every few hours during the day.
We're currently writing a website that will need to use the data from the access database. This website (for the time being) will have only read only capabilities. Meaning there will only need to be one way transfer of data (Access -> SQL).
I'm imaging there's a way to perform this data migration from access to SQL server programatically. Does anyone have any links to something I can read about?
If this practice sounds odd, and you'd like to suggest another way to do this (or a situation where data can go both ways (Access -> SQL, SQL -> Access), that's perfectly fine.
The company is going to continue using Access 2003 for their business functionality. There's no way around that. But I'd like to build the (readonly) website on top of SQL Server.
The strategy you outlined can be very challenging. You could use INSERT queries to copy new Access rows to SQL Server, as described in another answer.
However, if you have changes to existing Access rows, and you also want those changes propagated to SQL Server, it won't be so simple. And it will be more complicated still if you want deleted Access rows deleted from SQL Server, too.
It seems more reasonable to me to use a different approach. Migrate the data to SQL Server once. Then replace the tables in your Access database with ODBC links to the SQL Server tables. Thereafter, changes to the data from within your Access application will not require a separate synchronization step ... they will already be in SQL Server. And you won't need to write any code to synchronize them.
If your concern is that the connections between the web server and SQL Server be read-only, just set them up that way. You can still independently allow read-write permissions for your Access application.
To do the initial data migration and set the SQL Server automatically, I would use the SQL Server Migration Assistant. The only thing you should definitely change that I can think of would be to turn off the Identity property on any columns that have it - to be explained below (MS Access calls Identity autonumber). Once you have your tables loaded, you can set up a dsnless connection to the database (and tables) you just created.
I haven't used the method just linked, but I believe it allows you to use SQL Server authentication to connect to the db. The benefit of using this method is you can easily change which SQL Server instance and/or database your are connecting to for development and testing.
There might be a better, automated way, but you can create several insert queries doing left joins from the primary key of the Access table to the SQL Server table, and putting a WHERE clause that specifies the SQL Server PrimaryKey must be null. This is why you need to turn off the Identity property in the SQL Server tables, so that you can insert the new data.
Finally, put the name of each query in one function, then run the function periodically.
I have used Microsoft's free SQL Server Migration Assistant (SSMA) to migrate Access to SQL Server. The tool is very simple to use. The only problem I have encountered with the tool was overloaded data types when migrating. What I mean by this is a small string will get converted to a NVARCHAR(MAX) in some instances. Otherwise, the tool is very handy and can be reused after setting up a 'profile'.

SQL Server 2005 Auditing

Background
I have a production SQL Server 2005 server to which 4 different applications connect and make changes.
There are no foreign keys and in some cases no primary keys.
Unfortunately throwing the whole thing out and starting from scratch is not an option.
So my solution is to start migrating each of the applications to a service layer approach so that there is only one application directly connecting to the database.
However there are problems that need to be fixed before that service layer is written and all the applications are migrated over.
So rather than make changes and hope they don't break any one of the 4 badly written applications (with no way of quickly testing all functionality) my solution is to start auditing the database
Problem
How do I audit what stored procedures, tables, columns, views are being accessed/updated/called by each user on SQL Server 2005.
I can find out which tables are being updated but I have no idea which columns and by what users.
I also don't know if certain tables are being accessed only through stored procedures/views.
I know that SQL Server 2008 has better auditing features but if I could do this without spending money that would be great. That said if the best solution is to upgrade or buy software that's also an option.
Check out SQL Server 2008's CDC feature. You can't use this directly in 2005 but you can write a trigger for each table to log all data changes to a new audit table. i.e. you'd have an audit table for each table in your db, with all the same columns plus some additional columns saying what the operation was and when it occurred.
If the nature of your applications means you can get user information and/or application information from CURRENT_USER and APP_NAME() you could include that information in the audit table too.
And check out this answer for more goodness.

sys.dm_db_missing_index_details returns no rows

I have tried to look at sys.dm_db_missing_index_details to check for missing indexes on my SQL Server 2005 database. It is returning no rows.
It is possible that it should be empty but highly unlikely as I have not added ANY indices on any table (except the ones you get by creating primary keys). I am also running unit tests as well as adhoc development tests (using Linq to SQL) against it so there is some activity against it.
Do I need to turn on the capturing of this data?
Is this only supported on certain editions of SQL Server 2005?
Thanks in advance for any efforts to help.
It appears that it's on by default - although check any shortcut you are using to launch and make sure it's not launching with a -x
From http://msdn.microsoft.com/en-us/library/ms345524(v=SQL.90).aspx
This feature can only be disabled if an instance of SQL Server is started by using the -x argument with the sqlservr command-prompt utility.
Also you'll want to know that the table is populated as queries are run if SQL Server uses the query optimizer - this table is cleared when you restart SQL Server.
From http://msdn.microsoft.com/en-us/library/ms345434(v=SQL.90).aspx
Information returned by sys.dm_db_missing_index_details is updated when a query is optimized by the query optimizer, and is not persisted. Missing index information is kept only until SQL Server is restarted. Database administrators should periodically make backup copies of the missing index information if they want to keep it after server recycling.
Lastly there is an article that goes into the limitations here that you may or may not know about, but I'll post in case someone else happens across this post and needs: http://msdn.microsoft.com/en-us/library/ms345485(v=SQL.90).aspx
I didn't see anything about the feature being missing in some versions but you WILL need certain permissions:
Users must be granted the VIEW SERVER STATE permission or any permission that implies the VIEW SERVER STATE permission to query this dynamic management view.
Another option is to query the plan cache directly -- this also has the benefit that it can get you the query that wants the index. There's a related question here on SO -- the answer from BankZ has a complete SQL script that does the job.
It may run slowly though - the plans are in XML format, so with this query, we're asking SQL Server to do lots of XML work rather than table work. But it does work :-)
And as with the main missing index table, the plan cache is cleared down if SQL Server is restarted.

Resources