I have the need to store the user information temporarily on SQL server to serve audit purpose. My idea is :
because SQL can only audit changed data, but I also want to store user's information who made the changes, so I've to figure somethings out to achieve this
when user log in to the application, create a local temporary table (#), name it after the user's current SPID , somethings like : #sp56, and store the information you need in there
when the audit triggers are fired, it will find the uses's nesscessary informations based on the SPID and fill the audit table with them
I also tried to audit the data in EF, but found it too complicated and not worthy to spend so much time in it
So my question is, is this possible using EF and SQL-Server? If there're any other better alternatives, I'm happy to hear!
Related
I have a generic service account that is used by a web application to call a stored procedure to delete records in a temporal table I have. The stored procedure gets the web user id (which is what I want to track).
For updates and inserts, it's easy - insert/update and make sure the UserId field is populated with the web application's user id.
I'm stuck on deletions - the only mechanism I can think of is to do an update on the UserId field with the web user id and then do a delete. This obviously is one more step than I want, but it also yields an additional record in the history table I don't want.
Is there a best practice to solve this?... or do I already have the best available solution here?
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.
I have a profile page (less than 10k users) and I need to track every change and update that is made through out the application, by the users. Whether a user updates the profile picture or adds an extra space in a "comments" field, I need to store the previous data.
In short: I need to store everything.
Is there some sort of "tracking-history-and-changes-in-sql-server" software or do I have to implement it myself?
If I have to implement it myself I can think of three ways to do it:
I keep everything in the same table
but I add a key column that
specifies which row is active
and which is old.
I add a new table called history
where I store the column name that had the
change, when it was changed and what
the old data was.
I add a history table for each table
in the database. It looks the same
but only keep track of each tables
history.
Has anyone had a similar problem and how did you solve it?
This was built using mvc 4 and it's a
normal website.
EDIT
I'm mostly interested in existing solutions/software, but If there are none I would have to do it myself.
Has anyone used SQL Data Compare?
Where I worked last everything had to be logged fully. (working with goverment organisations). We never updated or deleted data.
What you would do is have a start date and an end date on each row. To do an update you would update the old data to have an enddate then insert a new row in the table. To do a delete you would put an enddate on the row with a null enddate. We also had an "updated by" column to put the userid
I used the third approach to do that but didn't create a history table for all tables of my DB but history tables for most important tables. You can use triggers to do that , create trigger for Update. You can read more about Triggers here and here
Microsoft offers Change Tracking and Change Data Capture for awhile now. These technically offer the tracking of all your changes in your database, which suits your purpose. Just note that CT is available in most versions, whereas CDC used to be only available in Enterprise until SQL Server 2016, where they made it available for Standard too.
ApexSQL Log does pretty much the same as well, but if you're using SQL Server then it's integrated in your software already.
have you considered enabling full transaction logging on your database and then using some of the log reading tools to monitor data changes. ApexSQL Log is by far the best log reader on the market but there are other solutions out there. SQL Log Rescue from Red Gate is free but it's only for sql server 2000.
Using this approach you dont need to make any other changes in your database or in your application since every transaction is automatically logged when database is in full recovery mode.
Hope this helps.
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...
I need to create in my DB a log, that every action in the program should be written there.
I will also want to store additional data to it for example have the table and row the action was applied to.
In other words I want the log to be dynamic and should be able to refer to the other tables in the database.
The problem is, I don't know how to relate all the tables to this log.
Any ideas?
You have two choices here:
1) modify your program to add logging for every db access
2) add triggers to each table in your db to perform logging operations.
I don't recommend one logging table for all tables. You will have locking issues if you do that (every insert, update and delete in every table woudl have to hit this one, bad idea). Create a table for each table that you want to audit. There are lots of possible designs for the table, but they usually include some variant of old vlaue, new value, date changed, and user who did the change.
Then create triggers on each table to log the changes.
I know SQL Server 2008 also has a systemic way to set up auditing, this would be easier to set up than manual auditing and might be enough to lure your company into using 2008.